NGBA - Animal Defenders II

Programación Orientada a Objetos (Tower defense - kingdom rush)

Moderator: julianmartinez16

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

NGBA - Animal Defenders II

Post by checholiolinares » Thu Jul 26, 2018 6:36 am

Integantes:
  • Jose Luis Victoria
  • Sergio Peñaloza

Repositorio en GIT

https://github.com/checholiolinaeres/An ... ders-2.git

Last edited by checholiolinares on Sun Aug 12, 2018 11:18 pm, edited 2 times in total.
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

User avatar
fellurchin
Posts: 9
Joined: Thu Jul 26, 2018 6:30 am

Re: NGBA - Animal Defenders II

Post by fellurchin » Thu Jul 26, 2018 7:05 am

Logo de la empresa
Image

Logo del juego
Image

Backlog
Image
"Si te he fallado te pido perdón de la única forma que es, abriendo las puertas de mi corazon para cuando decidas volver. Yo solo quiero tu amistad." -Albert Einstein
----
Jose Luis Victoria V.
Programacion y diseño orientado a objetos

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

Re: NGBA - Animal Defenders II

Post by checholiolinares » Fri Jul 27, 2018 7:49 pm

Que Hemos Hecho?

- Se definió la narrativa del juego.
- Se pensaron las mecanicas base.
- Definicion del cronograma (backlog).
- se reinventó el personaje principal a partir de concept de la precuela del juego.
- se han hecho los modelos 3D basicos del personaje principal (Bullet) y los enemigos normales (robots televisor) con sus respectivos rigs.
- Animacion Idle de bullet

BackLog
Image

Bullet del juego anterior
Image

Modelo 3D de Bullet
Image

Rig de Bullet
Image

Animacion Idle de bullet
Image



Modelo 3D de enemigos(las partes negras son configuradas dentro de unity, funcionan como mascara)
Image

¿Que vamos a hacer?
para la siguiente semana se van a realizar los modelos 3D de props (proyectiles, arboles, piezas de robots destruidos, chatarra,inicio de la Torre e inicio de la base), se realizarán pruebas de papel para la UI y menús, despues de las pruebas inicia la programacion de ui

¿Que dificultades tiene?

por el momento no se han presentado dificultades
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

User avatar
xacarana
Site Admin
Posts: 1028
Joined: Fri Jan 15, 2016 6:13 pm

Re: NGBA - Animal Defenders II

Post by xacarana » Tue Jul 31, 2018 6:29 am

Image

Recuerden publicar los avances de programación también.
Andrés Bedoya Tobón
Profesor
"I only smile in the dark, I only smile when it's complicated" Raybiez

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

Re: NGBA - Animal Defenders II

Post by checholiolinares » Sun Aug 05, 2018 9:58 pm

¿Qué hemos hecho?
  • Se modelaron y animaron los personajes secundarios que trabajan en las torres.
  • Se escribió el script de movimiento de la camara.
  • Se empezó el script del movimiento del zorro.
  • Se modeló, texturizó e importó el asset que corresponde al objetivo hacia el cual camina el zorro
Personaje secundario
Image

Codigo del control de la camara

Code: Select all

using UnityEngine;

public class ControlCamara : MonoBehaviour {
    Vector3 posicionCentro; //posicion central del mouse en los pixeles de la pantalla

    public static Transform objSeleccionado; //transform del objeto que está seleccionado actualmente, se define static por comodidad a la hora de ubicarlo en el UI
    Transform zorro, baseDef; //transforms del zorro y la base principal 

    Ray ObjSeleccionadoRayo; 
    Camera cam; //una camará que será en la que se realizarán las acciones escritas aqui

    float minX; //minima coordenada en X de la pantalla para que la camara se desplace
    float maxX; //maxima coordenada en X de la pantalla para que la camara se desplace
    float minY;
    float maxY;
    float t; //parametro t que se usará en las interpolaciones de zoom y velocidad de movimiento
    public float velocidad = 1; //velocidad cambiable desde el editor
    
    // Use this for initialization
    void Start ()
    {
        cam = this.GetComponent<Camera>(); // se define la camara
        zorro = GameObject.FindWithTag("Player").transform; // se define el zorro
        baseDef = GameObject.Find("base").transform; //se define la base
        objSeleccionado = baseDef; // se define por defecto que el objeto seleccionado es la base
        posicionarCamara(objSeleccionado,true); // se posiciona la camara mirando a la base
        posicionCentro = new Vector3(Screen.width / 2, Screen.height / 2, 0); //se define el centro de la pantalla
        minX = Screen.width / 10;
        maxX = Screen.width - (Screen.width / 10);
        minY = Screen.height / 7;
        maxY = Screen.height - (Screen.height / 7);
        t = 0f;
    }
	
	// Update is called once per frame
	void FixedUpdate ()
    {

        t += Input.GetAxis("Mouse ScrollWheel"); //defino el factor t para interpolar entre el FOV maximo y el minimo

        if (Input.GetMouseButtonDown(2)) //se reestablece el zoom si se presiona el boton central del mouse
            t = 0;

        Zoom(t); // se llama una funcion para realizar un zoom en la camara

        velocidad = Mathf.Lerp(1, 0.2f, t); //se calcula la velocidad siendo 1 el maximo valor y 0.2 el minimo dependiendo del nivel de zoom

        Vector3 posicionMouse = Input.mousePosition; //se define un Vector3 que se va a ir actalizando conforme el mouse se mueva por la pantalla
        Vector3 direccion = new Vector3((posicionMouse - posicionCentro).x, 0, (posicionMouse - posicionCentro).y).normalized; //se calcula la direccion en la que se está moviendo el mouse desde el centro hasta su posicion

        //Inicia las validaciones para decidir si la camara s emueve o no
        if (posicionMouse.x >= maxX)
            transform.position += direccion * velocidad; // se le suma la direccion multiplicado con la velocidad a un vector que transforme la coordenada y del mouse en la z de la camara
        if (posicionMouse.x <= minX)
            transform.position += direccion * velocidad;
        if (posicionMouse.y >= maxY)
            transform.position += direccion * velocidad;
        if (posicionMouse.y <= minY)
            transform.position += direccion * velocidad;

        //validacion de si se dio doble click a un objeto que sea seleccionable
        if (DobleClick())
        {
            ObjSeleccionadoRayo = cam.ScreenPointToRay(Input.mousePosition); //se lanza un rayo desde el punto donde esta el mouse en la pantalla hacia adelante de la camara
            RaycastHit hit; // se crea un hit de rayo para poder analizar su informacion
            if (Physics.Raycast(ObjSeleccionadoRayo, out hit))
                if (hit.collider.gameObject.GetComponent<InteraccionCamara>() != null) // si el objeto con el que golpeó tiene un componente especifico, este pasará a ser el objeto actualmente seleccionado
                {
                    objSeleccionado = hit.collider.gameObject.transform;
                    posicionarCamara(objSeleccionado, false); // y se posiciona la camara con ese objeto en el centro
                }
        }
	}

    /// <summary>
    /// posiciona la camara en donde el objeto seleccionado se encuentre con un determinado desfase para que esté centrado
    /// </summary>
    /// <param name="seleccionado">el objeto seleccionado actual</param>
    /// <param name="inicio">Define si es el primer posicionamiento de la camara o ya es a traves del usuario</param>
    /// <param name="desfaseZ">El desfase en la coordenada Z, por defecto está definido en -20</param>
    /// <param name="desfaseY">El desfase en la coordenada Y, por defecto está definido en 20</param>
    void posicionarCamara(Transform seleccionado,bool inicio,float desfaseZ = -20f,float desfaseY = 20f)
    {
        Vector3 desfasar = new Vector3(1, desfaseY, desfaseZ);
        if (!inicio)
            transform.position = Vector3.Lerp(transform.position, new Vector3(seleccionado.position.x, seleccionado.position.y + desfaseY, seleccionado.position.z + desfaseZ), Time.fixedTime);
        else
            transform.position = new Vector3(seleccionado.position.x, seleccionado.position.y + desfaseY, seleccionado.position.z + desfaseZ);       
    }


    /// <summary>
    /// funcion que simula un doble click para pasarlo como un input mas
    /// </summary>
    /// <returns></returns>
    public bool DobleClick()
    {
        int clicks = 0;
        bool retorno = false;
        if (Input.GetButtonDown("Fire1"))
        {
            clicks++;
            if (Input.GetButtonDown("Fire1") && clicks == 1)
            {
                clicks++;
                if (clicks >= 2)
                {
                    clicks = 2;
                    retorno = true;
                }
            }
        }
        return retorno;
    }

    /// <summary>
    /// funcion que simula zoom de camara interpolando linealmente un valor maximo y minimo de FOV
    /// </summary>
    /// <param name="t"></param>
    void Zoom(float t)
    {
        cam.fieldOfView = Mathf.Lerp(60, 20, t);
    }
    

}
Ejemplo de movimiento de camara
Image


Movimiento del zorro

Code: Select all

using UnityEngine;
using UnityEngine.AI;

public class Aber : MonoBehaviour {

    private GameObject[] navs; //array de objetos sobre los que se pueda navegar
    private NavMeshAgent agent; //el agente navmesh del zorro
    public GameObject prefabObj; //el prefab que representará el objetivo al que se dirigirá el zorro
    Ray rayo; 
    RaycastHit hit;
    private Animator anim; // componente animator del zorro

    // Use this for initialization
    void Start () {
        navs = GameObject.FindGameObjectsWithTag("Caminable"); //se agregan todos los objetos navegables en escena
        agent = GetComponent<NavMeshAgent>(); //se inicializa el navmesh agent del personaje
        anim = this.gameObject.GetComponentInChildren<Animator>();//se obtiene el componente animator del hijo de este objeto
	}
	
	// Update is called once per frame
	void FixedUpdate () {

        rayo = Camera.main.ScreenPointToRay(Input.mousePosition); //se dispara un rayo desde la posicion del mouse
        if (Input.GetButtonDown("Fire1")) //
        {
            if (Physics.Raycast(rayo, out hit)) //se castea un rayo desde la posicion con un click y se guarda la informacion de colision en el hit
            {               
                if (hit.collider.gameObject.CompareTag("Caminable")) //si el rayo golpea un objeto en el que se pueda navegaar
                {
                    if (GameObject.FindWithTag("Objetivo") == null) // y si no existe un objetivo
                        Instantiate(prefabObj, hit.point, Quaternion.identity); // se crea un objetivo en el pundo donde se clickeó
                }
            }
        }

        if (GameObject.FindWithTag("Objetivo") != null) // si el objetivo existe...
        {
            agent.destination = GameObject.FindWithTag("Objetivo").transform.position; //el destino del navmesh agent será el objetivo
            if (Vector3.Distance(transform.position,agent.destination) <= 2f) //si el zorro se encuentra a 2 unidades o menos del objetivo...
                Destroy(GameObject.FindWithTag("Objetivo")); //se destruye el objetivo
        }
        else
            agent.destination = transform.position; // en caso de que no exista objetivo el destino es su propia posicion

        anim.SetFloat("Velocidad", agent.velocity.magnitude); // control de animación
    }
}

Ejemplo de movimiento del zorro
Image

Objetivo del zorro

Image

¿Qué vamos a hacer?
  • Se terminarán los modelos 3D de los enemigos y se pondrán físicas en la cola y orejas del zorro.
  • Se terminarán los modelos 3D de las trampas y as torres.
  • Se programará la UI con las interacciones de movimiento de cámara, compra, dinero e información del personaje.
¿Qué dificultades tenemos?

por el momento el principal problema ha sido lograr una iluminación agradable para el nivel, puesto que no es prioridad para el curso, este problema se irá solucionando a lo largo del semestre poco a poco para no retrasar procesos prioritarios
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

Re: NGBA - Animal Defenders II

Post by checholiolinares » Sun Aug 12, 2018 11:17 pm

¿Qué hemos hecho?
  • Se creó el modelo 3D de los enemigos con animaciones.
  • Se creó el modelo 3D de las trampas cuyo material varia según su tipo.
  • Se creó el modelo 3D de la torre con animacion de ser levantada (se coordina con la animación de los personajes secundarios).
  • Se mejoró el shader del personaje principal (Bullet).
  • Se creó un material animado para las explosiones de las trampas
  • Se agregó una UI provisional.
  • Se creó un sistema de tienda consistente en Scriptable Objects.
  • Se implementó un sistema de compra.
  • Se dibujaron Sprites para la UI.



Modelo del enemigo con animacion Idle

Image

Image




Trampa

Image




Torre con animación
Image

Image



Shader de Bullet

Image



Material de la Explosión

Image




UI provisional

Image



ScriptableObject

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu()]
public class Producto : ScriptableObject
{
    public string Descripcion;
    public int precio;


    //Parametros que se van a pasar al componente torre a la hora de colocarla
    
        //aqui van los parametros
}
Articulo que se usa como plantilla de un producto generico

Code: Select all

using UnityEngine;
using UnityEngine.UI;

public class Articulo: MonoBehaviour
{
    public Producto producto; //Asset de producto correspondiente a este articulo
    Text precio; //texto que mostrará el precio
    Text Descripcion; //texto que mostrará la descrpcion

    private void OnEnable() // aqui se suscriben metodos de este escript para ser manejados en la UI
    {
        UiEventHandler.Compra += Comprar;
    }

    private void OnDisable()
    {
        UiEventHandler.Compra -= Comprar;
    }

    //se obtienen los componentes necesarios 
    private void Update()
    {
        precio = Buscar("Precio").GetComponent<Text>();
        precio.text = " $ " + producto.precio.ToString();
        Descripcion = Buscar("Descripcion").GetComponent<Text>();
        Descripcion.text = producto.Descripcion;
    }

    //funcion para buscar un GameObject especifico dentro de los hijos
    GameObject Buscar(string nombre)
    {
        GameObject retorno = null;

        foreach (Transform t in transform)
        {
            if (t.name == nombre)
                retorno = t.gameObject;
        }
        return retorno;
    }


    //Funcion para comprar, esta se suscribe al evento comprar de la UI
    public void Comprar()
    {
        MainProps props = GameObject.Find("Main").GetComponent<MainProps>();
        if (props.Dinero >= producto.precio)
        {
            props.Dinero -= producto.precio;
            props.ArticuloComprado = producto;
        }
    }
}
Script que llena la tienda con un numero especifico de articulos

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TiendaAsset : MonoBehaviour
{
    public List<Producto> productos;
    List<GameObject> articulos;
    public GameObject plantilla;
    MainProps propiedadesMain;
    

    private void Start()
    {
        articulos = new List<GameObject>();
        for (int i = 0; i < productos.Count; i++)
        {
            articulos.Add(Instantiate(plantilla,transform));
        }
        for (int i = 0; i < articulos.Count; i++)
        {
            articulos[i].GetComponent<Articulo>().producto = productos[i];
        }
    }
}


Sprites Dibujados

Image

¿Qué vamos a hacer?
  • Se terminarán de modelar y texturizar a los otros 2 tipos de enemigos.
  • Se Terminará el modelo de la otra torre.
  • Se Programará el sistema para posicionar torres.
  • Se Programarán el comportamiento de las torres y sus clases.
  • Se programarán el comportamiento de los enemigos y sus clases.
  • En caso de quedar tiempo se empezará a programar el Boss final del nivel
  • Se creará el escenario base sin decoraciones de props.
¿Que dificultades hemos tenido?

por el momento se ha presentado una dificultad a la hora de decidir como implementar el comportamiento de bullet, se le dio una solución y se espera con contenido futuro del curso mejorar el script, como es algo sobre el comportamiento de un actor probablemente tambien se presentará el problema al programar a los enemigos y las torres
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

User avatar
xacarana
Site Admin
Posts: 1028
Joined: Fri Jan 15, 2016 6:13 pm

Re: NGBA - Animal Defenders II

Post by xacarana » Tue Aug 14, 2018 6:38 am

Image

Van bien con las evidencias, pero no hay nada en el repositorio, las evidencias de código se deben publicar en el foro y actualizar en el repositorio. Próxima revisión strike si no cumplen con este requisito.
Andrés Bedoya Tobón
Profesor
"I only smile in the dark, I only smile when it's complicated" Raybiez

User avatar
fellurchin
Posts: 9
Joined: Thu Jul 26, 2018 6:30 am

Re: NGBA - Animal Defenders II

Post by fellurchin » Wed Aug 15, 2018 7:23 pm

Adelanto de la semana actual

Se diseñaron las clases de los enemigos, las torres y las trampas.


Image

Image

Image
"Si te he fallado te pido perdón de la única forma que es, abriendo las puertas de mi corazon para cuando decidas volver. Yo solo quiero tu amistad." -Albert Einstein
----
Jose Luis Victoria V.
Programacion y diseño orientado a objetos

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

Re: NGBA - Animal Defenders II

Post by checholiolinares » Mon Aug 20, 2018 11:55 pm

¿Qué hemos hecho?
  • Se modeló al enemigo tipo tanque
  • Se realizaron las clases de los enemigos, las trampas y las torres
  • Se adecuó el proyecto para poder trabajarse desde ambos computadores
  • Se escribió un script para uno de los tipos de enemigos con el objetivo de practicar herencia(no han sido terminadas)
Modelo del enemigo
Image

Clase Enemigo

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Enemigo:MonoBehaviour
{
    private Transform tran;
    private NavMeshAgent agent;
    private Vector3 target;
    private float salud;
    private float velocidad;
    private float danno;
    private int comportamientoFase;


    public virtual void Atacar()
    {

    }

    #region Getters y Setters

    public NavMeshAgent Agent
    {
        get
        {
            return agent;
        }

        set
        {
            agent = value;
        }
    }

    public Vector3 Target
    {
        get
        {
            return target;
        }

        set
        {
            target = value;
        }
    }

    public float Salud
    {
        get
        {
            return salud;
        }

        set
        {
            salud = value;
        }
    }

    public float Velocidad
    {
        get
        {
            return velocidad;
        }

        set
        {
            velocidad = value;
        }
    }

    public float Danno
    {
        get
        {
            return danno;
        }

        set
        {
            danno = value;
        }
    }

    public Transform Tran
    {
        get
        {
            return tran;
        }

        set
        {
            tran= value;
        }
    }

    public int ComportamientoFase
    {
        get
        {
            return comportamientoFase;
        }

        set
        {
            comportamientoFase = value;
        }
    }

    #endregion
}
Clases Escritas
fellurchin wrote:
Wed Aug 15, 2018 7:23 pm
Adelanto de la semana actual

Se diseñaron las clases de los enemigos, las torres y las trampas.


Image

Image

Image
Clase de robot

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class Robot : Enemigo
{
    
    GameObject prefabExplosion;
    MainProps props;
    float energia;
    Animator anim;
    LineRenderer linea;

	// Use this for initialization
	void Start () {
        energia = 30;
        Tran = transform;
        Agent = GetComponent<NavMeshAgent>();
        Target = Tran.position;
        Salud = Random.Range(200, 205);
        Velocidad = Random.Range(20, 25);
        Danno = Random.Range(10, 15);
	}
	
	// Update is called once per frame
	void FixedUpdate () {
        if (Vector3.Distance(Tran.position, Target) <= 1)
        {
            ComportamientoFase = 1;
        }
        else
        {
            ComportamientoFase = 0;
        }
        Comportamiento(ComportamientoFase);

        anim.SetFloat("velocidad", Agent.velocity.magnitude);
	}

    void Comportamiento(int fase)
    {
        switch (fase)
        {
            case 0:
                {
                    Agent.destination = props.BaseDef.transform.position;
                }
                break;
            case 1:
                {
                    anim.SetBool("atacando", true);
                    DannoPorTic(2);
                }
                break;
            default:
                Agent.destination = Tran.position;
                break;
        }
    }

    public IEnumerator DannoPorTic(int segundosTic)
    {        
        // hacer daño
        yield return new WaitForSeconds(segundosTic);  
    }

    public override void Atacar()
    {
        Vector3[] posiciones = { Tran.position, Target };
        linea.SetPositions(posiciones);
    }

    void Morir()
    {

    }
}

¿Que se va a hacer?

Por el momento pensamos terminar todos los objetivos de la semana pasada que no pudieron ser alcanzados debido a dificultades

¿Que dificultades hemos tenido?

Debido a parciales y entregas de otras materias el objetivo de la semana anterior no pudo ser cumplido e su totalidad, afortunadamente segun el backlog esos objetivos representaban el trabajo de 2 semanas
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

User avatar
checholiolinares
Posts: 24
Joined: Thu Jul 26, 2018 6:24 am

Re: NGBA - Animal Defenders II

Post by checholiolinares » Sun Aug 26, 2018 9:48 pm

¿Qué hemos hecho?
  • Se realizó el modelo 3D del jefe final del nivel
  • Se escribió y probó el script de el ataque de la torre
  • Se empezó a escribir el script de la trampa
Jefe final
Froggo

Script Ataque de torre

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AtaqueTorre : MonoBehaviour {

    float vida, danno, rango,vidaEnemigo;
    GameObject enemigo;
    
	// Use this for initialization
	void Start () {
        vida = 100;
        danno = 1;
        enemigo = null;
        rango = 10f;
	}
	
	// Update is called once per frame
	void FixedUpdate () {
        Debug.Log(enemigo.name);
        
        if (enemigo != null)
        {
            Invoke("HacerDanno", 1f);
        }
	}

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Enemigo") && enemigo == null)
        {
            enemigo = other.gameObject;
        }
    }

    private void OnTriggerExit(Collider other)
    {
        enemigo = null;
    }

    public void HacerDanno()
    {
        enemigo.GetComponent<Enemigo>().Vida -= danno;
    }
}
Script de la trampa

Code: Select all

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DannoTrampa : MonoBehaviour {

    private float danno;
    private float activacion;
    private GameObject explosion;
    private string tipo; //pasar propiedad de producto

	// Use this for initialization
	void Start () {
        explosion = GameObject.Find("Explosion prefab");
        switch (tipo)
        {
            case "vida":
                {
                    danno = 100f;
                }
                break;
            case "velocidad":
                {
                    danno = 60f; //porcentaje
                }
                break;
        }
        activacion = 10f;
	}
	
	// Update is called once per frame
	void FixedUpdate () {
		
	}

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Enemigo") && activacion == 10f)
        {
            while (activacion > 0)
            {
                Activar();
            }
            Explotar();
        }
    }

    private void Explotar()
    {
        transform.GetChild(1).GetComponent<SkinnedMeshRenderer>().enabled = false;
        //cosas raras con listas
        Instantiate(explosion, transform.position, Quaternion.identity);
        //cuando acabe de explotar se destruye
    }

    IEnumerator Activar()
    {
            activacion--;
            yield return new WaitForSeconds(0.1f);       
    }
}
¿Que vamos a hacer?

vamos a terminar los comportamientos del resto de enemigos, Variantes de torres y trampas y terminar de implementar el diseño del nivel. Se espera que con las siguientes 2 semanas de trabajo se saque la primera versión funcional para realizar pruebas

¿Que dificultades tenemos?

las ultimas 2 semanas nos e ha podido avanzar con tanta prisa como las anteriores, afortunadamente logramos remontar el proceso y esperamos terminar la base del juego pronto
Sergio Felipe Pañaloza Herrera
Programación y diseño orientado a objetos

Image

Post Reply