0

Person に Quest オブジェクトを追加しようとしています。一方は成功し、もう一方は nullreferenceexception を返します。ここで何が間違っているのでしょうか? PS プレーヤーとリクエスターは、Unity インスペクターで設定されます。

public class GameCreator : MonoBehaviour {
     private Quest quest;
     public Player player;
     public Requestor requestor;

     void Start() {
         quest = createQuest();
         requestor.thisPerson.SetQuest(quest); //this is the problem
         player.thisPerson.SetQuest(quest);
     }
}

public class Player : MonoBehaviour {
     public Person thisPerson;

     void Start() {
           thisPerson = new Person("Name");
     }
}

public class Requestor: MonoBehaviour {
     public Person thisPerson;

     void Start() {
           thisPerson = new Person("Name");
     }
}

public class Person {
     public Quest quest;

     void SetQuest(Quest quest) {
           this.quest = quest;
     }
}

これがうまくいかない理由はありますか?

4

2 に答える 2

3

変数の初期化を に移動します。次のドキュメントAwake()を参照してください(言い換え):

Awake は、ゲームの開始前に変数またはゲームの状態を初期化するために使用されます。また、Start を使用して情報をやり取りします。

あなたの記述方法GameCreator.Start()は、Unity がスクリプトを呼び出す任意の順序に依存しています。 GameCreatorが最初に呼び出されるオブジェクトである可能性があります。この場合、他のスクリプトは値を初期化していません。

その他の考えられるエラー:

  1. を明示的にインスタンス化することはありませんrequestor。これは Unity のインスペクターで行われたと仮定します。
  2. null を返す可能性のある「createQuest()」が含まれていませんでした。
于 2013-10-28T15:09:48.757 に答える
1

Jordak が言ったように、Start メソッドは任意の順序で実行できるため、別のコンポーネントの Start に依存することはできません。この問題に対処するには、いくつかの方法があります。

  • 基本的な初期化コードを Awake() に移動できます。ただし、これでは 2 レベルの初期化しかできず、将来的には不十分になる可能性があります。
  • プロジェクト設定でスクリプトの優先度を調整できます。ただし、これは実際には C# の方法ではありません。これにより、コードがそこから明らかではないロジックに依存するようになるためです。
  • クラスの初期化で thisPerson フィールドを初期化する代わりに、パブリック プロパティを作成してアクセスします。(いずれにせよ、パブリック フィールドは C# では悪い習慣です)。このプロパティでは、フィールドを返す前に null かどうかを確認し、null の場合は初期化できます。
于 2013-10-29T09:45:54.077 に答える