Unidad: nulo al hacer una nueva instancia de clase

Me quedé atrapado en una situación bastante tonta: estoy haciendo una nueva instancia de la clase genérica pero devuelve “nula” nula.

Rule rule2 = new Rule(); // initiate the class Debug.Log(rule2); //1st debug rule2.RuleSetup(r: "CaughtEnough", li: 0); //setting up the parameters Debug.Log(rule2.rule); //2nd debug 

La primera depuración me da

  null UnityEngine.Debug:Log(Object) 

al mismo tiempo, la configuración de los parámetros funciona, y la segunda depuración me da

  CaughtEnough UnityEngine.Debug:Log(Object) 

que es lo que se supone que debe estar en la instancia de clase apropiada.

Un problema (solo hasta ahora) que me está dando es que si en esta instancia de la clase de regla llamo

  Invoke(rule, 0f); 

me da el error NullReferenceException. Pero al mismo tiempo, la función real

  CaughtEnough(); 

funciona bien y como se esperaba

¿Alguna idea de cuál podría ser la fuente del problema y cómo superarlo?

UPD también publica una parte de configuración de la clase Rule, como se le pidió, aunque es sencilla

 public class Rule : MonoBehaviour { public string rule; public int leftInt; public Dictionary leftDict; public float countdown; public int outcome; public CatchManager catchMan; public Net net; // Use this for initialization void Start () { RuleSetup(); } public void RuleSetup(string r = "NoRule", int li = 0, Dictionary ld = null, float cd = float.PositiveInfinity) { rule = r; leftInt = li; leftDict = ld; countdown = cd; } ..... 

 public class Rule : MonoBehaviour{} Rule rule2 = new Rule(); 

No puede usar palabras clave new para crear una nueva instancia si está heredando de MonoBehaviour .

Debería obtener una excepción que diga :

Está intentando crear un comportamiento en mono con la palabra clave ‘nueva’. Esto no esta permitido. MonoBehaviours solo se puede agregar usando AddComponent (). Alternativamente, su script puede heredar de ScriptableObject o no tener una clase base

Su código habría funcionado si tuviera public class Rule {} pero tiene public class Rule : MonoBehaviour {} .

Crear una nueva instancia de clase que se deriva de MonoBehaviour :

Clase de ejemplo:

 public class Rule : MonoBehaviour { public Rule(int i) { } } 

Si MonoBehaviour de MonoBehaviour , debes usar GameObject.AddComponent o GameObject.AddComponent para crear una nueva instancia de este.

 Rule rule2 = null; void Start() { rule2 = gameObject.AddComponent(); } 

O

 public Rule rulePrefab; Rule rule2; void Start() { rule2 = Instantiate(rulePrefab) as Rule; } 

Si el script de Rule ya existe y está adjunto al GameObject, no es necesario crear / agregar / instanciar una nueva instancia de ese script. Simplemente use la función GetComponent para obtener la instancia del script del GameObject al que está conectada.

 Rule rule2; void Start() { rule2 = GameObject.Find("NameObjectScriptIsAttachedTo").GetComponent(); } 

Notará que no puede usar el parámetro en el constructor cuando deriva su script de MonoBehaviour .



Crear una nueva instancia de clase que NO se deriva de MonoBehaviour :

Clase de ejemplo: (Tenga en cuenta que no deriva de ” MonoBehaviour

 public class Rule { public Rule(int i) { } } 

Si no hereda de MonoBehaviour , debe usar la new palabra clave para crear una nueva instancia de la misma. Ahora, puede usar el parámetro en el constructor si lo desea.

 Rule rule2 = null; void Start() { rule2 = new Rule(3); } 

EDITAR :

En la última versión de Unity, la creación de una nueva instancia de una secuencia de comandos que hereda de MonoBehaviour con la palabra clave new puede no proporcionarle un error y puede no ser null también, pero no se ejecutarán todas las funciones de callback . Estos incluyen las funciones Awake , Start , Update y otros. Entonces, todavía tiene que hacerlo correctamente como se menciona en la parte superior de esta respuesta.

Solo un seguimiento, cómo terminé haciéndolo y por qué:

  1. Ya no MonoBehaviour clase Rule de MonoBehaviour para evitar el seguimiento de creación y eliminación de gameObjects, lo que parecía ser el problema.

  2. Como el método Invoke no existe en clases genéricas, lo reemplacé con reflection, como se describe aquí