Object reference not set to an instance of an object, Unity

huangapple go评论98阅读模式
英文:

Object reference not set to an instance of an object, Unity

问题

当敌人生成时,我尝试在这里初始化他 enemy.Init();,但出现了错误“Object reference not set to an instance of an object”(对象引用未设置为对象的实例)。但在这里 Debug.Log(enemy._enemyHealth);,我能够获取到敌人的生命值。如果敌人是类 'Usual Enemy' 并且它是从 'Enemy' 类继承的,而且我将会有更多的敌人子类,我如何从这里初始化我的敌人呢?

你可以尝试使用以下方法来解决这个问题:

  1. 确保预制件正确配置: 确保你的敌人预制件(Prefab)已正确配置,并且在预制件上已经附加了相应的脚本组件。确保 enemy.Init(); 中的 enemy 不为 null。

  2. 检查子类的初始化方法: 如果你有多个敌人子类,确保每个子类都实现了 Init() 方法。你可以在每个子类中重写 Init() 方法,以确保它们的初始化逻辑正确执行。

  3. 使用多态: 你可以使用多态来确保调用适当的子类的 Init() 方法。这样,无论你使用哪个子类的实例,都会调用正确的初始化方法。

例如,如果你的 enemy 变量是 Enemy 类型的引用,但实际上它是一个子类的实例,那么你可以这样调用 Init() 方法:

  1. enemy.Init();

这将根据实际的对象类型调用正确的 Init() 方法。

确保在你的子类中正确实现了 Init() 方法,以便它可以执行所需的初始化逻辑。如果你仍然遇到问题,可以提供更多的代码或信息,以便我可以提供更具体的帮助。

英文:

So when enemy is spawned i try to init him here enemy.Init(); but had error Object reference not set to an instance of an object. But here Debug.Log(enemy._enemyHealth); i get number of enemy health. How i can Init my enemy from here if enemy has class 'Usual Enemy' and it extends from this class 'Enemy' and i wiil have more enemy child cllases?

I vave class Enemy

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. public abstract class Enemy : MonoBehaviour
  6. {
  7. private GameObject _player;
  8. private Animator _animator;
  9. private Rigidbody _rigidbody;
  10. private bool _isSpawned;
  11. private const int _enemySpavnTime = 5;
  12. [SerializeField] public float _enemyHealth;
  13. [SerializeField] protected float _rotationSpeed = 10f;
  14. [SerializeField] protected float _moveSpeed;
  15. [SerializeField] protected float _damage;
  16. [SerializeField] protected DamageBox _damageBox;
  17. [SerializeField] protected TriggerBox _triggerBox;
  18. private EnemyCondition _enemyCondition = EnemyCondition.Dead;
  19. private enum EnemyCondition
  20. {
  21. Spawn,
  22. Run,
  23. Attack,
  24. Dead
  25. }
  26. void Start()
  27. {
  28. _rigidbody = GetComponent<Rigidbody>();
  29. _animator = GetComponent<Animator>();
  30. _player = GameObject.FindWithTag("Hero");
  31. _damageBox.HeroHited += enemyAttack;
  32. _triggerBox.HeroInAttackRange += enemyGetAngry;
  33. _triggerBox.HeroOutAttackRange += enemyGetChill;
  34. }
  35. void Update()
  36. {
  37. if (_player != null)
  38. {
  39. if (_enemyCondition == EnemyCondition.Run)
  40. {
  41. EnemyPlayerRotation(_player);
  42. } else if (_enemyCondition == EnemyCondition.Attack)
  43. {
  44. EnemyPlayerRotation(_player);
  45. }
  46. }
  47. }
  48. void FixedUpdate() {
  49. if (_enemyCondition == EnemyCondition.Run)
  50. {
  51. EnemyPlayerFollow();
  52. }
  53. }
  54. public virtual void Init() {
  55. enemySpawn();
  56. }
  57. protected virtual void EnemyPlayerFollow() {
  58. Vector3 direction = transform.TransformDirection(new Vector3(0, 0, 1));
  59. _rigidbody.velocity = direction * _moveSpeed;
  60. }
  61. protected virtual void EnemyPlayerRotation(GameObject target) {
  62. Vector3 direction = (target.transform.position - transform.position).normalized;
  63. Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0, direction.z));
  64. transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * _rotationSpeed);
  65. }
  66. public virtual void EnemyDamage(float damage)
  67. {
  68. _enemyHealth -= damage;
  69. if (_enemyHealth <= 0) {
  70. PoolManager.Instanse.Despawn(gameObject);
  71. }
  72. }
  73. public virtual void enemySpawned() {
  74. _enemyCondition = EnemyCondition.Run;
  75. _rigidbody.isKinematic = false;
  76. _animator.SetTrigger("Run");
  77. StopCoroutine(SpawnMoveUp());
  78. Debug.Log("enemySpawned");
  79. }
  80. protected virtual void enemyAttack(Hero trigger)
  81. {
  82. if (_enemyCondition == EnemyCondition.Attack) {
  83. trigger.HeroDamage(_damage);
  84. }
  85. }
  86. protected virtual void enemyGetAngry() {
  87. _enemyCondition = EnemyCondition.Attack;
  88. _animator.SetTrigger("Attack");
  89. }
  90. protected virtual void enemyGetChill() {
  91. _enemyCondition = EnemyCondition.Run;
  92. _animator.SetTrigger("Run");
  93. }
  94. protected virtual void enemySpawn() {
  95. _animator.SetTrigger("Spawn");
  96. _animator.speed = 0.0f;
  97. StartCoroutine(SpawnMoveUp());
  98. }
  99. IEnumerator SpawnMoveUp()
  100. {
  101. float spawnStage = 0.0f;
  102. Vector3 startPoint = transform.position;
  103. while(spawnStage <= 1.0f) {
  104. transform.position = Vector3.Slerp(startPoint, new Vector3(transform.position.x, 0, transform.position.z), spawnStage);
  105. spawnStage += Time.deltaTime/_enemySpavnTime;
  106. yield return null;
  107. }
  108. _animator.speed = 1.0f;
  109. }
  110. }

And I have class that spawns enemies

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class EnemiesSpawner : MonoBehaviour
  5. {
  6. [SerializeField] private Levels[] _levelsList;
  7. private List<GameObject> _enemiesQueue = new List<GameObject>();
  8. private List<GameObject> _levelEnemiesList = new List<GameObject>();
  9. private List<int> _levelEnemiesCount = new List<int>();
  10. private bool _isBossSpawned = false;
  11. // private int _currentLevel = PlayerPrefs.GetInt("currentLevel") - 1;
  12. private int _currentLevelNumber = 0;
  13. private float _reloadPause = 0;
  14. private int currentEnemiesListPos = 0;
  15. private int allEnemiesCount = 0;
  16. private float _reloadTime;
  17. private float _spawnRadius;
  18. private float _spawnOfsetRadius = 2f;
  19. [SerializeField] private GameObject _boss;
  20. [SerializeField] private GameObject _spawnPoint;
  21. void Start() {
  22. Levels currentLevelObj = _levelsList[_currentLevelNumber];
  23. _levelEnemiesCount.AddRange(currentLevelObj.enemiesCount.ToArray());
  24. _levelEnemiesList = currentLevelObj.enemiesPrefabs;
  25. _spawnRadius = currentLevelObj.spawnRadius;
  26. _reloadTime = currentLevelObj.spawnReload;
  27. foreach(int num in _levelEnemiesCount) {
  28. allEnemiesCount += num;
  29. }
  30. while(_enemiesQueue.Count < allEnemiesCount){
  31. int randomIndex = Random.Range(0, _levelEnemiesCount.Count);
  32. if (_levelEnemiesCount[randomIndex] == 0) {
  33. continue;
  34. } else {
  35. _enemiesQueue.Add(_levelEnemiesList[randomIndex]);
  36. _levelEnemiesCount[randomIndex] --;
  37. }
  38. }
  39. }
  40. public void SetPlayerForSpawn (GameObject player) {
  41. _spawnPoint = player;
  42. }
  43. void Update ()
  44. {
  45. if (_spawnPoint != null){
  46. SpawnEnemies();
  47. }
  48. }
  49. public void SpawnEnemies()
  50. {
  51. _reloadPause += Time.deltaTime;
  52. if (_reloadPause >= _reloadTime && currentEnemiesListPos < allEnemiesCount) {
  53. GameObject go = PoolManager.Instanse.Spawn(_enemiesQueue[currentEnemiesListPos],new Vector3((Random.value < 0.5f) ? Random.Range(_spawnPoint.transform.position.x + _spawnOfsetRadius, _spawnPoint.transform.position.x + _spawnRadius) : Random.Range(_spawnPoint.transform.position.x - _spawnOfsetRadius, _spawnPoint.transform.position.x - _spawnRadius), -5, (Random.value < 0.5f) ? Random.Range(_spawnPoint.transform.position.z + _spawnOfsetRadius, _spawnPoint.transform.position.z + _spawnRadius) : Random.Range(_spawnPoint.transform.position.z - _spawnOfsetRadius, _spawnPoint.transform.position.z - _spawnRadius)), Quaternion.identity);
  54. Enemy enemy = go.GetComponent<Enemy>();
  55. Debug.Log(enemy._enemyHealth);
  56. enemy.Init();
  57. _reloadPause = 0;
  58. currentEnemiesListPos ++;
  59. } else if (currentEnemiesListPos == allEnemiesCount && _isBossSpawned == true) {
  60. Instantiate(_boss,new Vector3(0,0,0), Quaternion.identity);
  61. _isBossSpawned = true;
  62. }
  63. }
  64. }

So when enemy is spawned i try to init him here enemy.Init(); but had error Object reference not set to an instance of an object. But here Debug.Log(enemy._enemyHealth); i get number of enemy health. How i can Init my enemy from here if enemy has class 'Usual Enemy' and it extends from this class 'Enemy' and i wiil have more enemy child cllases?

答案1

得分: 0

问题不在于“敌人”对象。它不是空的。如果你看一下调用栈中的最后一个引用,你会发现它是“_animator”字段。

这可能是因为你在Unity引擎调用“敌人”对象的“Start”方法之前调用了“Init”函数。

英文:

The problem is not about "enemy" object. It is not null. If you look at the last reference on your call stack, you see that it is "_animator" field.

It's probably because you call the "Init" function before the "enemy" object's "Start" method called by Unity engine.

huangapple
  • 本文由 发表于 2023年6月1日 18:54:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76381166.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定