type - this class c#




Unity: nulo ao criar uma nova instância de classe (2)

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

Você não pode usar uma new palavra-chave para criar uma nova instância se estiver herdando do MonoBehaviour .

Você deve obter uma exceção que diz :

Você está tentando criar um MonoBehaviour usando a palavra-chave 'new'. Isso não é permitido. MonoBehaviours só pode ser adicionado usando AddComponent (). Como alternativa, seu script pode herdar de ScriptableObject ou nenhuma classe base

Seu código teria funcionado se você tivesse public class Rule {} mas você tem public class Rule : MonoBehaviour {} .

Criando uma nova instância de classe que deriva do MonoBehaviour :

Exemplo de classe:

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

    }
}

Se você herdar do MonoBehaviour , deverá usar GameObject.AddComponent ou Instantiate para criar uma nova instância dele.

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

OU

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

Se o script de Rule já existir e estiver anexado ao GameObject, você não precisará criar / adicionar / instanciar uma nova instância desse script. Apenas use a função GetComponent para obter a instância de script do GameObject ao qual ela está anexada.

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

Você notará que não pode usar o parâmetro no construtor ao derivar seu script do MonoBehaviour .

Criando uma nova instância de classe que NÃO deriva do MonoBehaviour :

Exemplo de classe: (Note que não deriva de " MonoBehaviour "

public class Rule
{
    public Rule(int i)
    {

    }
}

Se você não herdar do MonoBehaviour , deverá usar a new palavra-chave para criar uma nova instância dela. Agora, você pode usar o parâmetro no construtor, se quiser.

Rule rule2 = null;

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

EDITAR :

Na versão mais recente do Unity, a criação de uma nova instância de um script que herda do MonoBehaviour com a new palavra-chave pode não dar erro e pode não ser null também, mas todas as funções de retorno de chamada não serão executadas . Isso inclui as funções Awake , Start , Update e outras. Então, você ainda tem que fazer isso corretamente, como mencionado no topo desta resposta.

Eu fiquei preso em uma situação bem idiota: estou criando uma nova instância da classe genérica mas ela retorna "estranho" null.

    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

1º debug me dá

    null
    UnityEngine.Debug:Log(Object)

ao mesmo tempo, configurando os parâmetros funciona, e o segundo debug me dá

   CaughtEnough
   UnityEngine.Debug:Log(Object)

que é o que deveria estar na instância de classe apropriada.

Um (só até agora) problema que está trazendo para mim é que, se eu ignorar essa instância de classe de regra, eu chamo

   Invoke(rule, 0f);

isso me dá o erro NullReferenceException. Mas ao mesmo tempo a função real

   CaughtEnough();

funciona muito bem e como esperado.

Alguma idéia do que poderia ser a fonte do problema e como superá-lo?

UPD também postando parte da configuração da classe Rule, como solicitado, embora seja simples

public class Rule : MonoBehaviour {

public string rule;

public int leftInt;
public Dictionary<string, int> 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<string, int> ld = null,  float cd = float.PositiveInfinity) {
    rule = r;
    leftInt = li;
    leftDict = ld;
    countdown = cd;
}
.....

Apenas um follow up, como acabei fazendo isso e por quê:

  1. Eu não herdo mais a classe Rule do MonoBehaviour para evitar rastrear o cretion e a exclusão dos gameObjects, o que parecia ser a dor.

  2. Como o método Invoke não existe em classes genéricas, eu o substitui por reflection, como descrito here





null