5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

NullReferenceException: Object reference not set to an instance of an object の解決例

Last updated at Posted at 2020-12-28

エラーの様子

エラー文

スクリーンショット 2020-12-28 16.25.02.png
和訳サイトにかけたところ
NullReferenceException:オブジェクト参照がオブジェクトのインスタンスに設定されていない。
とのこと。

エラーで指定されているファイルの全体(修正前)

using UnityEngine;
using UnityEngine.AI;

[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(EnemyStatus))]
public class EnemyMove : MonoBehaviour
{
    [SerializeField] private LayerMask raycastLayerMask;
  // [SerializeField]private PlayeController playercontroller;
  private NavMeshAgent _agent;
  private RaycastHit[] _raycastHits = new RaycastHit[10];
  private EnemyStatus _status;

  private void Start()
  {
    _agent = GetComponent<NavMeshAgent>();
  }

  // private void Update()
  // {
  //   _agent.destination = playerController.transform.position; 
  // }

  public void OnDetectObject(Collider collider)
  {
    if(!_status.IsMovable)
    {
        _agent.isStopped = true;
        return;
    }
    if(collider.CompareTag("Player"))
    {
      _agent.destination = collider.transform.position;
      
      var positionDiff = collider.transform.position - transform.position;
      var distance = positionDiff.magnitude;
      var direction =positionDiff.normalized;
      var hitCount = Physics.RaycastNonAlloc(transform.position,direction,_raycastHits,distance,raycastLayerMask);
      Debug.Log("hitCount: " + hitCount);
      if(hitCount == 0){
        _agent.isStopped = false;
        _agent.destination = collider.transform.position;
      }
      else
      {
        _agent.isStopped = true;
      }
    }
  }
}

これらからわかるように、今回のエラーはif(!_status.IsMovable)が呼び出せていないことエラーだった。

解決までの試行錯誤

とりあえず検索したところエラーの解決方法はスペルミスか、inspectorのcomponentのattachし忘れを確認するべしとのこと。
確認したがあっていた。困ったので参考にしている本をまた最初から見直した。その結果記述漏れしている部分があり、追記によって修正できた。

解決方法

このファイルで使える変数の用意だけでなく、他のファイルで決めている値(component)をもってくる記述をすることでエラー解消した。具体的には下記の通り。

略
  private void Start()
  {
    _agent = GetComponent<NavMeshAgent>();
    _status = GetComponent<EnemyStatus>();
  }
略

EnemyStatusは親クラスにattachしていたが、無条件に子要素にそれがそのまま適用されることはなかったので、GetComponentする必要があった。

原因

requireによって呼び出されたクラスをインスタンス化させることをしなかったため。

詳しく書くと、ファイルを跨いでデータのやり取りをする場合は

  • [RequireComponent(typeof(EnemyStatus))]のように指定されたファイルを読み込み、
  • 値の入れものをprivate EnemyStatus _status;のように準備し、
  • _status = GetComponent<EnemyStatus>();のように呼び出されたクラスをインスタンスで使えるようにする

という手順が必要で、その3つ目を飛ばしてしまったのが原因だった。

参考

別パターンの解決方法:
https://qiita.com/KONTA2019/items/3a47a1a297bb18e2b795

5
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?