2015-11-28 4 views
-2

Я пытаюсь добавить систему оценки в свою игру. Однако я получаю эту ошибку всякий раз, когда я играю, и астероиды больше не уничтожат, когда они сталкиваются либо с игроком, либо с пулей.Ошибка «NullReferenceException»

Мой сообщение об ошибке состоит в следующем: NullReferenceException: Ссылка на объект не указывает на экземпляр объекта DestroyByContact.OnTriggerEnter2D (UnityEngine.Collider2D прочие) (на активы/скрипты/DestroyByContact.cs: 47)

I следует отметить, что на всех игровых объектах есть и теги.

И некоторые Код:

using UnityEngine; 
using System.Collections; 

public class DestroyByContact : MonoBehaviour { 

    public GameObject explosion; 
    public GameObject playerExplosion; 
    public int scoreValue; 
    private GameController gameController; 

    void start() { 
     GameObject gameControllerObject = GameObject.FindWithTag ("GameController"); 
     if (gameControllerObject != null) { 
      gameController = gameControllerObject.GetComponent <GameController>(); 
     } 

     if (gameController == null) 
     { 
      Debug.Log ("Cannot find 'GameController' script"); 
     } 
    } 

    void OnTriggerEnter2D(Collider2D other){ 
     if (other.tag == "Boundary") { 
      return; 
     } 

     Instantiate(explosion, transform.position, transform.rotation); 

     if (other.tag == "Player") { 
      Instantiate(playerExplosion, other.transform.position, other.transform.rotation); 
     } 

     gameController.AddScore (scoreValue); 
     Destroy(other.gameObject); 
     Destroy(gameObject); 
    } 
} 

using UnityEngine; 
using System.Collections; 
using UnityEngine.UI; 

public class GameController : MonoBehaviour { 

    public GameObject[] asteroids; 
    public Vector3 spawnValues; 
    public int asteroidCount; 
    public float spawnWait; 
    public float startWait; 
    public float waveWait; 

    public GUIText scoreText; 
    private int score; 

    void Start() { 
     score = 0; 
     UpdateScore(); 
     StartCoroutine (spawnWaves()); 
    } 

    IEnumerator spawnWaves() { 

     yield return new WaitForSeconds (startWait); 

     while (asteroidCount > 0) { 
      for (int i = 0; i < asteroidCount; i++) { 
       GameObject asteroid = asteroids[Random.Range(0, asteroids.Length)]; 
       Vector3 spawnPosition = new Vector3 (spawnValues.x, Random.Range (-spawnValues.y, spawnValues.y), spawnValues.z); 
       Quaternion spawnRotation = Quaternion.identity; 
       Instantiate (asteroid, spawnPosition, spawnRotation); 
       yield return new WaitForSeconds (spawnWait); 
      } 
      yield return new WaitForSeconds (waveWait); 

      if (asteroidCount <= 95) { 
       asteroidCount += 5; 
      } 
     } 
    } 

    public void AddScore (int newScoreValue) { 
     score += newScoreValue; 
     UpdateScore(); 
    } 

    void UpdateScore() { 
     scoreText.text = "Score:" + score; 
    } 
} 
+0

Какая строка 47 из 'DestroyByContact.cs'? И как вы думаете, что переменная там установлена? «NullReferenceException» обычно довольно тривиально для отладки: что вы сделали, чтобы попытаться понять проблему? –

+0

Линия 47: gameController.AddScore (scoreValue) ;. И, честно говоря, я новичок в этом, и я использую некоторые учебники, чтобы попытаться учиться. Я не уверен, как отладить это. Одна вещь, которую я знаю, это если я положу строку 47 ниже функций destroy, которые она все еще работает, но не добавляет счет (который, я думаю, потому, что игровой объект больше не существует для запуска кода). – MarkHughes88

+1

Марк, вместо использования FindWithTag, назначает GameController из иерархии. И попробуйте еще раз, если вы не знаете, как сделать этот снимок экрана вашего единства с нами. –

ответ

0

Я бы сказал, что лучше идеей было бы установить gameController после Instantiate внутри контроллера. Если я правильно понял, ваш GameController порождает астероиды, которые имеют DestroyOnContact, прикрепленных к сборке prefab/predefined? Если это так, рассмотреть возможность сделать это так:

GameController

var go = Instantiate (asteroid, spawnPosition, spawnRotation) as GameObject; 
if (destroyable != null) 
{ 
    var destroyable = go.GetComponent<DestroyByContact>(); 
    if (destroyable == null) 
    { 
     //Something else got instantiated, destroy it as we don't need it here 
     Destroy(destroyable); 
    } 
    else 
    { 
     destroyable.gameController = this; 
    } 
} 

DestroyOnContact

//just change accessor from private to public 
public GameController gameController; 

//Get rid of stuff that would set gameController in Start() 

//Also check if gameController != null before you call .AddScore() 
+0

Я пытаюсь ссылаться на скрипт игрового контроллера, прикрепленный к игровому объекту игрового контроллера, поэтому могу сказать, что он увеличивает счет игрока, когда астероид уничтожается. – MarkHughes88

+1

Nothings останавливает вас от другого, как я показал вам. Фактически при правильной инъекции зависимостей вам следует вводить GameController извне (конструктор не является допустимым способом для MonoBehaviour, к сожалению), как в моем примере, вместо того, чтобы находить его изнутри из DestroyOnContact. – mwilczynski

+0

Я не совсем уверен, как это работает. Я попытался поместить его в свой код безрезультатно. – MarkHughes88

Смежные вопросы