El null de Unity
Parte de la sección Fundamentos de scripting en Unity del Journey de Unity de Coddy. Lección 60 de 85.
Un objeto de Unity tiene dos partes: el objeto de C# que conserva tu script y el objeto del motor que hay detrás. Destroy(obj) elimina la parte del motor al final del fotograma, pero tu variable sigue apuntando a la parte de C#, así que, en términos de C# puro, no es null. Unity redefine == para contemplar esto: una vez destruido el objeto, obj == null es true, y la prueba abreviada !obj también. Esto es el null falso de Unity.
?., ?? e is null no usan ese ==. Comprueban la referencia de C#, que aún existe, así que permiten que se ejecute la llamada, y acceder al objeto destruido lanza MissingReferenceException: The object of type 'Transform' has been destroyed but you are still trying to access it. Esta etiqueta muestra el nombre del líder de la carrera, que puede ser eliminado (destruido):
[SerializeField] private Transform leader;
void Update()
{
// lanza una excepción cuando se destruye leader: string shown = leader?.name ?? "nobody";
string shown = leader != null ? leader.name : "nobody";
Debug.Log("Leader: " + shown);
}Para cualquier cosa que provenga de UnityEngine.Object (GameObjects, componentes, tus scripts), comprueba con == null, != null o if (obj), y reserva ?. y ?? para objetos de C# puro, como las cadenas. Recuerda también que Destroy espera hasta el final del fotograma: hasta entonces, el objeto sigue vivo y == null es false.
Desafío
IntermedioDetén los errores del dron cuando se destruya su objetivo.
- En
Update(), reemplaza ambas líneas porif (target != null), la comprobación de nulo propia de Unity. - Dentro de esta, escribe
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);.
Pulsa «Jugar»: el dron persigue al objetivo y después espera sin errores en la Consola. Luego pulsa «Comprobar».
Pruébalo tú mismo
using UnityEngine;
public class Chaser : MonoBehaviour
{
[SerializeField] private Transform target;
[SerializeField] private float speed = 2f;
void Start()
{
Destroy(target.gameObject, 2f); // el objetivo se destruye después de 2 segundos
}
void Update()
{
Vector3 goal = target?.position ?? transform.position;
transform.position = Vector3.MoveTowards(transform.position, goal, speed * Time.deltaTime);
}
}
Todas las lecciones de Fundamentos de scripting en Unity
1Conceptos básicos de C# en Unity
Hola, UnityVariablesLos decimales necesitan una fTexto en la consolaVariables que recuerdanIf y ElseComparar númerosRepaso: Recolector de monedas7Bucles y métodos
Repetir con forBucles dentro de buclesEscribir un métodoMétodos que respondenArraysRepaso: escalera10Encontrar cosas
Buscar por nombreEtiquetasBuscar por tipoLas referencias vencen a FindEl null de UnityRepaso: moneda más cercana13Proyecto: Esquiva los bloques
El corredorBloques desde el cielo2Haz que se mueva
Coloca el cuboMuévelo en cada fotogramaGira cada segundoDirige con las teclasRepaso: conduce el cubo5Vectores
Sumar vectoresDireccionesEspacio local y mundialVelocidad diagonalDistancia entre objetosVector3 es una estructuraRepaso: piloto de dron8GameObjects y componentes
Referencias en el InspectorObtener un componenteComponentes faltantesAñadir un componenteRequireComponentMostrar y ocultarRepaso: interruptor de luz3El Inspector
Campos del InspectorSerializeFieldFloats y MathfAtributos del InspectorRepaso: Ascensor6Transformaciones y jerarquía
Padres e hijosIza la banderaEscalaMira las cosasMuévete hacia un puntoRepaso: Luna en órbita9Proyecto: Atrapa la estrella
El cazadorUna estrella fugaz12El ciclo de vida de un script
Awake y StartUpdate y LateUpdateOnEnable y OnDisableEl orden del ciclo de vidaRepaso: registrador del ciclo de vidaPractica por tu cuenta: Playground de Unity