You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 20:04:54