Unity Spain

Post Antiguos => General (Antiguo) => Mensaje iniciado por: brok en Noviembre 12, 2015, 07:43:10 PM

Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 12, 2015, 07:43:10 PM
El siguiente problema es que cuando instancio o duplicar el enemigo, al aver varios enemigos unos 5 o 6 no se detruye el enemigo que estoy golpeando, se destruye uno al hazar ¿como puedo solucionarlo?. using UnityEngine;
using System.Collections; public class vidaPlayerAI : MonoBehaviour
{
    Transform playerai;
    public static float vidaEnemigo = 100f;
    public static int ScoreValor = 10;    public static void RestarVidaEnemigo()
    {
        
        vidaEnemigo -= 20f;        if (vidaEnemigo <= 0f)
        {            Destroy(GameObject.FindGameObjectWithTag("Enemigo"));
            ScoreManager.score += ScoreValor;
            vidaEnemigo += 100;
                    }
        
    }
}Otro script.using UnityEngine;
using System.Collections;
public class ColisionPlayerAI : MonoBehaviour
{
    Transform player;
    AudioSource patadaAudio;
    public float sinkSpeed = 0.5f;
    void Start()
    {
        patadaAudio = GetComponentInParent<AudioSource>();
        player = GameObject.FindGameObjectWithTag("Player").transform;
    }
    void OnTriggerEnter(Collider colision)
    {        if (colision.gameObject.CompareTag("Player"))        {            vidaPlayer.RestarVida();
            patadaAudio.Play();
            Player.damaged = true;
            player.Translate(-Vector3.forward * sinkSpeed);
        }
    }
    
    
}Otro script. using UnityEngine;
using System.Collections;public class enemigoManager : MonoBehaviour {
    public GameObject enemigo;
    public float spawnTime = 10f;
    public Transform[] spawnPoints;
    // Use this for initialization
    void Start ()
    {
        InvokeRepeating("Spawn", spawnTime, spawnTime);
        
    }   
    void Spawn()
    {
                int spawnPointIndex = Random.Range(0, spawnPoints.Length);        Instantiate(enemigo, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
    }
Título: Hacer que el enemigo se destruya
Publicado por: mrpacogp en Noviembre 12, 2015, 07:51:16 PM
Vaya cacao te llevas.Cada enemigo debe de contener su propia clase de vida, no se si es una de esas dos que pones, porque lo mas conveniente es cuando un enemigo entra en colision con una bala, el mismo se quita vida y cuando llegue a cero se muere.Y tú ahí tienes en la otra clase un metodo que se llama RestarVida(es conveniente que los nombres de los métodos sean mas claros...)y no queda claro a quien se aplica.Espero que me hayas entendido pero solo leerte ya ha sido complejo de por si.
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 12, 2015, 07:59:49 PM
El metodo RestarVida se le aplica al jugador
Este script le resta la vida al enemigo,using UnityEngine;
using System.Collections;public class  ColisionPlayer: MonoBehaviour
{
    Transform playerT;
    public float sinkSpeed = 0.5f;
    AudioSource PatadaSonido;
    Player player;
    void Start()
    {
        playerT = GameObject.FindGameObjectWithTag("Player").transform;
        PatadaSonido = GetComponentInParent<AudioSource>();
        player = GetComponentInParent<Player>();
    }    void OnTriggerEnter(Collider colision)
    {        if (colision.gameObject.CompareTag("Enemigo"))        {            vidaPlayerAI.RestarVidaEnemigo();
            player.sliderAI.gameObject.SetActive(true);
            Player.damaged = true;
            PatadaSonido.Play();
            playerT.Translate(-Vector3.forward * sinkSpeed);
        }
        else
        {
            StartCoroutine(sliderEnemigo());
        }
        
   }    IEnumerator sliderEnemigo()
    {
        yield return new WaitForSeconds(5f);
        player.sliderAI.gameObject.SetActive(false);
        yield return null;
    }
}
Título: Hacer que el enemigo se destruya
Publicado por: mrpacogp en Noviembre 13, 2015, 11:39:06 AM
Yo te recomiendo que cada enemigo tenga una clase base en la cual al entrar en un trigger con un objeto tipo bala o lo que le haga daño, entonces le reste vida. 
Título: Hacer que el enemigo se destruya
Publicado por: kik195 en Noviembre 13, 2015, 12:04:15 PM
Destroy(GameObject.FindGameObjectWithTag("Enemigo"));puede ser que se te vuelva loco por destruir el objeto por el tag?si tienes varios objetos con ese mismo tag en escena no se veran influenciados?
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 13, 2015, 02:17:13 PM
Si ese creo yo que es el problema pero ya lo he intentado con un GameObject y el metodo RestarVidaEnemigo() esta en static y me sale error al poner la variable de GameObject, y el metodo RestarVidaEnemigo() tiene que estar en static, porque el script de colision esta dentro del esqueleto del personaje. 
Título: Hacer que el enemigo se destruya
Publicado por: francoe1 en Noviembre 13, 2015, 03:25:33 PM
Algo tan simple como un control de Salud no tiene que tener absolutamente nada estático, el problema se genera por 2 cosas, primero que cada vez que llamas la función RestarVidaEnemigo() esta se ejecuta en todos los Enemigos, y segundo "Destroy(GameObject.FindGameObjectWithTag("Enemigo"));" esto hace referencia al primer objeto que encuentra Unity con el tag "Enemigo". ¿Como se hace entonces?1- Creamos un componente y lo llamamos HealtControl (Nombre Opcional).2- Utilizamos 3 Métodos ApplyDamage ApplyCure, 1 Evento, 3 Variables.3- Actualizar cada parte del codigo donde aplicas cambia a la salud de cada personaje.Te Dejo el Codigo de Ej...
public class HealtControl : MonoBehaviour
{
public int MaxHealt = 100;
public int MinHealt = 0;

internal int CurrentHealt;
public delegate void DeathEvent();
public event DeathEvent Death:

void Start()
{
   if(CurrentHealt == 0)CurrentHealt = MaxHealt; // Asignamos MaxHealt como salud Inicial (CurrentHealt).
        Death += () => { Destroy(this.gameObject); } ;
 // Detectamos el Evento y Destruimos el Objeto.
}

internal void ApplyDamage(int Value)
{
   CurrentHealt -= Value; //Restamos Current healt por el valor de Value.
   CurrentHealt = Mathf.Clamp(CurrentHealt,MinHealt,MaxHealt); //Clampeamos los valores.
   if(CurrentHealt =< MinHealt)if(Death != null)Death(); //Detectamos si llego al minimo.
}

internal void ApplyCure(int Value)
{
   CurrentHealt += Value; //Aumentamos el valor de CurrentHealt.
   CurrentHealt = Mathf.Clamp(CurrentHealt,MinHealt,MaxHealt); //Clampeamos valores.
}
}

public class  ColisionPlayer: MonoBehaviour
{
    Transform playerT;
    public float sinkSpeed = 0.5f;
    AudioSource PatadaSonido;
    Player player;


    void Start()
    {
        playerT = GameObject.FindGameObjectWithTag("Player").transform;
        PatadaSonido = GetComponentInParent<AudioSource>();
        player = GetComponentInParent<Player>();
    }

    void OnTriggerEnter(Collider colision)
    {

        if (colision.gameObject.CompareTag("Enemigo"))
        {      
            //Vamos a utilizar una referencia a HealtControl para acceder a su metodo ApplyDamage().
            //Luego que hacemos la comprobacion de que existe dicho componente, vamos a llamar a la funcion ApplyDamage();
            var healt = colision.gameObject.GetComponent<HealtControl>(); //Tomamos el Componente HealtControl de la referencia.
            if(healt != null)healt.ApplyDamage(10);//Comprobamos si no es nulo y llamamos la funcion deseada.


            player.sliderAI.gameObject.SetActive(true);
            Player.damaged = true;
            PatadaSonido.Play();
            playerT.Translate(-Vector3.forward * sinkSpeed);


        }
        else
        {
            StartCoroutine(sliderEnemigo());
        }
       
   }

    IEnumerator sliderEnemigo()
    {
        yield return new WaitForSeconds(5f);
        player.sliderAI.gameObject.SetActive(false);
        yield return null;
    }

}
No te olvides de pasar por mi canal de YT, vas a entender cómo funcionan las variables con diferentes tipos de protección y acceso.
Otra Cosa, si necesitas detectar colisiones de cada parte del cuerpo ejemplo, Mano, Pie, Cabeza, es mejor crear referencia a las mismas y utilizar Physics comprobar la colisión. Código Ej.
public class BoneCollision : MonoBehaviour
{
//Creamos variables de referencia
public Transform[] BoneRef;
//Creamos Eventos
public delegate void Col(Transform ColRef);
public event Col ColBone;
//Conf
public float RadiusDetect = 5;
public LayerMask LayerCol;


void Update()
{
   //Creamos todos los los SphereCast para la deteccion de colision.
   RaycastHit hit;            
   foreach(Transform bone in BoneRef)
   {
      if (Physics.SphereCast(bone.position, RadiusDetect, bone.forward, out hit, 1,LayerCol))
        {
           if(ColBone != null)ColBone(hit.transform);
        }
   }        
}

void Start()
{
   ColBone += ((Transform Ref)=>
   {
      print(Ref.name);
      //Podemos Aplicar daño tambien
      var healt = Ref.GetComponent<HealtControl>(); //Tomamos el Componente HealtControl de la referencia.
            if(healt != null)healt.ApplyDamage(10);//Comprobamos si no es nulo y llamamos la funcion deseada.
   });
}
}
Todo esto lo hice sin comprobar si funcionaba, solo lo escribi..Este componente lo Asignas al Player y detecta todas las colisiones del player. Luego a la IA.. BoneRef -> Asignalo desde el inspector con el transform de la mano, pies y todos los que quieras que detecten colisión.Radius -> Radio del Collider de detecciónLayerCol -> Capas con la que queremos que colisione Saludos. 
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 13, 2015, 04:15:31 PM
Muchas gracias francoe1 aver si lo arreglo asin.
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 13, 2015, 05:40:54 PM
Se lo he intentado implementar pero sin exito siento mucho por todo lo que me as ayudado francoe1 pero no me resta vida ni destruye a ninguno ni al player ni al enemigo, de todas formas muchas gracias.Me sale un error en esta linea en el =<.el <.Severity    Code    Description    Project    File    Line
Error    CS1525    Invalid expression term '<'    curso.CSharp    C:\Users\ono\Documents\curso\Assets\script2\HealtControl.cs    24 
if(CurrentHealt =< MinHealt)if(Death != null)Death(); //Detectamos si llego al minimo.
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 13, 2015, 07:03:19 PM
Ya lo consegui pero le he puesto que le reste la vida al enemigo 20 y tengo que pegarle 7 o 9 patadas para restrle la vida y que destruya ell enemigo o me choco con el y lo destruyo.
Título: Hacer que el enemigo se destruya
Publicado por: francoe1 en Noviembre 13, 2015, 08:13:46 PM
El error es justamente por que esta mal puesta la expresión.. un error mio.
if(CurrentHealt <= MinHealt)if(Death != null)Death(); //Detectamos si llego al mínimo.
Solo cambia el "=<" por "<=" y llisto.
El problema de chocar y destruir es que deberias generar eventos, por ejemplo que al lanzar un Puñetazo se active la detección de la Mano si no estas atacando no deberia esta comprobando colisiones.
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 13, 2015, 09:07:40 PM
Gracias, ya lo arregle supuse que era eso y lo correji, nuevamente gracias por la informacion ¿dime cual es tu canal de youtube? que no lo encuentro.
Título: Hacer que el enemigo se destruya
Publicado por: francoe1 en Noviembre 14, 2015, 12:31:52 AM
" rel="external nofollow">
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 14, 2015, 07:53:26 PM
Modifique el codigo y ahora no me resta vida ni destruye ni me da ningun error ¿que puedo estar haciendo mal? using UnityEngine;
using System.Collections;
using System;public class vidaPlayerAI : MonoBehaviour
{
    public delegate void DeathEvent();
    public event DeathEvent Death;
    public int vidaEnemigoMax = 100;
    public int vidaEnemigoMin = 0;
    public int vidaEnemigoAI;    public int ScoreValor = 10;    public void RestarVidaEnemigo(int Value)
    {
        vidaEnemigoAI -= Value;
        vidaEnemigoAI = Mathf.Clamp(vidaEnemigoAI, vidaEnemigoMin, vidaEnemigoMax);
        if (vidaEnemigoAI <= 0) if (Death != null) Death();
    }        void Update()
    {
        if (vidaEnemigoAI == 0)
        
            vidaEnemigoAI = 100;
            Death += () => { Destroy(this.gameObject); };
            
                    if (vidaEnemigoAI == 0)
        {
            ScoreManager.score += ScoreValor;
            aumentarVidaEnemigo(0);
        }
            
        
        
                 }
    void aumentarVidaEnemigo(int Value)
    {
        vidaEnemigoAI += Value;
        vidaEnemigoAI = Mathf.Clamp(vidaEnemigoAI, vidaEnemigoMin, vidaEnemigoMax);
    }
} Otro script using UnityEngine;
using System.Collections;public class  ColisionPlayer: MonoBehaviour
{
    Transform playerT;
    public float sinkSpeed = 0.5f;
    AudioSource PatadaSonido;
    Player player;
    CapsuleCollider col;
    void Start()
    {
        playerT = GameObject.FindGameObjectWithTag("Player").transform;
        PatadaSonido = GetComponentInParent<AudioSource>();
        player = GetComponentInParent<Player>();
            }    void Update()
    {
        var healt = col.gameObject.GetComponent<vidaPlayerAI>();
        if (healt != null) healt.RestarVidaEnemigo(20);
    }    void OnTriggerEnter(Collider colision)
    {        if (colision.gameObject.CompareTag("Enemigo"))        {
            var healt = colision.gameObject.GetComponent<vidaPlayerAI>();
            if (healt != null)
            
                healt.RestarVidaEnemigo(20);                player.sliderAI.gameObject.SetActive(true);
                Player.damaged = true;
                PatadaSonido.Play();
                playerT.Translate(-Vector3.forward * sinkSpeed);
                        
        }
        else
        {
            StartCoroutine(sliderEnemigo());
        }
        
   }    IEnumerator sliderEnemigo()
    {
        yield return new WaitForSeconds(5f);
        player.sliderAI.gameObject.SetActive(false);
        yield return null;
    }
}Me da errorvar healt = col.gameObject.GetComponent<vidaPlayerAI>();NullReferenceException: Object reference not set to an instance of an object
ColisionPlayer.Update () (at Assets/script/player/ColisionPlayer.cs:24) 
Título: Hacer que el enemigo se destruya
Publicado por: brok en Noviembre 15, 2015, 10:47:00 AM
Ya esta arregkado solo me falta mejorar el script de vida para que recarge mas rapido.using UnityEngine;
using System.Collections;
using System;public class vidaPlayerAI : MonoBehaviour
{
    public delegate void DeathEvent();
    public event DeathEvent Death;
    public int vidaEnemigoMax = 100;
    public int vidaEnemigoMin = 0;
    public static int vidaEnemigoAI;
    int valorScore = 10;   void Start()
    {
        if (vidaEnemigoAI <= 0)
        vidaEnemigoAI = vidaEnemigoMax;
        Death += () => { Destroy(gameObject); };
        ScoreManager.score += valorScore;
        aumentarVidaEnemigo(0);
    }
           public void RestarVidaEnemigo(int Value, Vector3 hitPoint)
    {
        vidaEnemigoAI -= Value;
        vidaEnemigoAI = Mathf.Clamp(vidaEnemigoAI, vidaEnemigoMin, vidaEnemigoMax);
        if (vidaEnemigoAI <= 0) if (Death != null) Death();
    }
    public void aumentarVidaEnemigo(int Value)
    {
        vidaEnemigoAI += Value;
        vidaEnemigoAI = Mathf.Clamp(vidaEnemigoAI, vidaEnemigoMin, vidaEnemigoMax);
    }