Enemy预制体无法伤害Player:NullReferenceException问题求助
问题解决:生成器创建的Enemy预制体无法伤害Player并抛出空引用错误
问题现象
手动放置的Enemy可正常攻击Player,但通过生成器实例化的Enemy预制体无法触发伤害,同时抛出错误:
NullReferenceException: Object reference not set to an instance of an object Enemy.OnTriggerEnter2D (UnityEngine.Collider2D other) (at Assets/Scripts/Enemy/Enemy.cs:72)
错误原因
错误出在Enemy.cs第72行的OnTriggerEnter2D方法中:
- 手动放置的Enemy是在Unity编辑器Inspector面板中手动赋值了
playerHealth字段,因此能正常调用 - 预制体实例化时,
playerHealth字段未被赋值,且脚本Start方法中没有初始化该变量的逻辑,导致空引用
解决方案
1. 移除Inspector依赖,动态获取PlayerHealth组件
删掉依赖手动赋值的public PlayerHealth playerHealth字段,改用代码从Player对象上动态获取组件,避免预制体实例化后出现空引用。
2. 调用PlayerHealth的封装方法而非直接修改字段
PlayerHealth脚本中已提供TakeDamage方法,直接调用该方法比直接修改health字段更符合代码封装原则,也能统一处理死亡逻辑。
修改后的Enemy脚本
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Enemy : MonoBehaviour { public float health = 1; Animator animator; public float speed = 1; private GameObject player; public float damage; KillCounter killCounterScript; public GameObject [] itemDrops; public float Health { set { health = value; if (health <= 0) { Defeated(); } } get { return health; } } private void Start() { animator = GetComponent<Animator>(); player = GameObject.FindGameObjectWithTag("Player"); killCounterScript = GameObject.Find("KillCounterObject").GetComponent<KillCounter>(); } public void Defeated() { animator.SetTrigger("Defeated"); } public void RemoveEnemy() { Destroy(gameObject); killCounterScript.AddKill(); ItemDrop(); } private void Swarm() { transform.position = Vector2.MoveTowards(transform.position, player.transform.position, speed * Time.deltaTime); } private void Update() { Swarm(); } void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.CompareTag("Player")) { PlayerHealth targetHealth = other.GetComponent<PlayerHealth>(); if (targetHealth != null) { // 若需支持浮点伤害,修改PlayerHealth的TakeDamage参数为float即可 targetHealth.TakeDamage(Mathf.RoundToInt(damage)); } } } private void ItemDrop() { for (int i = 0; i < itemDrops.Length; i++) { Instantiate(itemDrops[i], transform.position, Quaternion.identity); } } }
补充:调整PlayerHealth的TakeDamage方法(可选)
如果希望支持浮点类型的伤害值,修改PlayerHealth的TakeDamage方法:
public void TakeDamage(float damage) { health -= damage; if (health <= 0) { Destroy(gameObject); } }
额外检查点
- 确保Enemy预制体的Collider2D组件勾选了
Is Trigger - 确保Player对象的Tag确实设置为
Player - 检查Enemy生成逻辑,确认预制体实例化代码无错误
内容的提问来源于stack exchange,提问作者Michael Fadare
相关产品推荐
相关产品推荐

