Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

Temas recientes

Error en script de bala tras el respawn del Player.

Iniciado por Packobilly, Agosto 31, 2019, 09:28:39 AM

Tema anterior - Siguiente tema
Agosto 31, 2019, 09:28:39 AM Ultima modificación: Agosto 31, 2019, 10:04:12 AM por Packobilly
Buenos días.
 
Les escribo como último recurso tras haberme devanado los sesos durante unos meses. Por motivos laborales no dedico todo el tiempo que me gustaría a Unity, pero les aseguro que llevo ya mucho tiempo con este problema y no doy con la tecla.
 
Resulta que cuando inicio el juego todo va perfecto con la bala; se instancia a la perfección y no da problemas. Pero cuando el player muere y reaparece en el punto de control asignado, al pulsar disparo para instanciar la bala, ésta se queda en el punto donde es instanciada, esto es, que no tiene velocidad, y me aparece el consabido error "NullReferenceException: Objet Refence not set to an instance or an object".
 
A priori puede parecer que el Player pierde su tag "Player"; en cierto modo es así, pues durante su muerte pasa a "untagged" para evitar que los enemigos sigan interaccionando con él, pero una vez realiza el respawn, vuelve a tener su tag "Player".
 
Espero que alguien pueda arrojar algo de luz al asunto, y gracias de antemano.
 

public class BulletManager : MonoBehaviour {
    public float speed;
    public float lifeTime;
    Rigidbody2D rb;
    public int damageValue = 1;
    PlayerController player;
    public GameObject impactPrefab;
    private void Awake()
    {
        rb = GetComponent<Rigidbody2D>();
        player = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerController>();
 
        if (player.faceRight && !player.verticalLook)  //Esta el la línea que me
                                                        //marca el error
        {
            rb.velocity = new Vector2(speed, rb.velocity.y);
        }
        else if (!player.faceRight && !player.verticalLook)
        {
            rb.velocity = new Vector2(-speed, rb.velocity.y);
            Vector3 bulletScale = transform.localScale;
            bulletScale.x *= -1;
            transform.localScale = bulletScale;
        }
        else if (player.faceRight && player.verticalLook || !player.faceRight && player.verticalLook)
        {
            rb.velocity = new Vector2(rb.velocity.x, speed);
            transform.Rotate(new Vector3(0f, 0f, 90f));
        }
        Destroy(gameObject, lifeTime);
}
    private void OnTriggerEnter2D(Collider2D col)
    {
            Instantiate(impactPrefab, transform.position, Quaternion.identity);
            Destroy(gameObject);
    }
}

 
 

Diría que el Awake se dispara antes de que hagas el respawn del player y por eso no lo encuentra.
 
Prueba a cambiar el Awake por un Start que se ejecuta después o  asigna el player sin buscar el tag desde el respawn del player al bulletmanager.
 
Otra opción es tener estados en el player y si este está muerto, que los enemigos no interactúen en vez de quitarle el tag. Esta me parece la mejor.

Agosto 31, 2019, 09:02:48 PM #2 Ultima modificación: Agosto 31, 2019, 09:03:34 PM por Deaymon
¿Cómo instancias la bala? Porque podrías usar el constructor de la clase BulletManager en lugar del Awake() para iniciar el movimiento de la bala. Así, pasas como parámetro la referencia al PlayerController y te ahorras usar el FindGameObjectWithTag().

Cita de: iRobb date=1567241384Prueba a cambiar el Awake por un Start que se ejecuta después
   


Eso fue una de las primeras cosas que probé, pero nada. Luego, si en el script de la salud del Player, no cambio a Untagged para correr todo el tema de la muerte y el respawning, todo va bien; salvando que las balas enemigas, así como éstos me siguen detectando y tal.
 

asigna el player sin buscar el tag desde el respawn del player al bulletmanager.

 
Es posible etiquetar al objeto player como "Player" desde el script del objeto bala?
 
Cita de: Deaymon date=1567278168¿Cómo instancias la bala? Porque podrías usar el constructor de la clase BulletManager en lugar del Awake() para iniciar el movimiento de la bala. Así, pasas como parámetro la referencia al PlayerController y te ahorras usar el FindGameObjectWithTag().
   


La bala es instanciada desde el script PlayerController, contenido en el objeto Player.
 
No estoy familiarizado con los constructores de clases, por lo que, con mi nivel actual, me sería "bastante imposible" llevar a cabo tu sugerencia. Si quieres, puedes encaminarme un poco; si no, no te preocupes y gracias.
 
 

Cita de: Packobilly date=1567528354Eso fue una de las primeras cosas que probé, pero nada. Luego, si en el script de la salud del Player, no cambio a Untagged para correr todo el tema de la muerte y el respawning, todo va bien; salvando que las balas enemigas, así como éstos me siguen detectando y tal.
   
   

asigna el player sin buscar el tag desde el respawn del player al bulletmanager.

   
      Es posible etiquetar al objeto player como "Player" desde el script del objeto bala?
   


Si claro. gamobject.tag = "lo que sea" lo puedes mientras el tag exista.

Cita de: iRobb date=1567528890Si claro. gamobject.tag = "lo que sea" lo puedes mientras el tag exista.
   


Desde el script contenido en la bala, gameobject.tag me cambia el tag del objeto que la instanció?

Cita de: Packobilly date=1567529010Desde el script contenido en la bala, gameobject.tag me cambia el tag del objeto que la instanció?
   


No me refiero a que la línea de código sea esa, tienes que sustituir el gameobject por el que toque, en este caso como se llame el player. De todos modos, creo que no es un buen enfoque.

Ok. Creo que con la ayuda prestada me será un poco menos difícil solucionarlo. Vamos a ver. Gracias!

Etiquetas: