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

Unity中NullReferenceException异常排查:炮弹发射功能失效

Unity炮弹发射功能NullReferenceException异常排查

问题描述

开发Unity游戏炮弹发射功能时,已完成组件配置并编写PlayerAttack与Ammo脚本,代码无语法错误,但运行时抛出NullReferenceException: Object reference not set to an instance of an object异常,按教程步骤操作多次核对仍无法解决。

相关代码

PlayerAttack脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerAttack : MonoBehaviour
{
    private float cooldownTimer = Mathf.Infinity;
    [SerializeField] private float attackCooldown;
    [SerializeField] private Transform firePoint;
    [SerializeField] private GameObject[] fireballs;
    private Animator anim;
    private PlayerControllert playerMovement;
     
    private void Awake()
    {
        anim = GetComponent<Animator>();
        playerMovement = GetComponent<PlayerControllert>();

    }
    private void Update()
    {
        if(Input.GetMouseButtonDown(0) && cooldownTimer > attackCooldown)
        {
            Attack();
        }
        cooldownTimer += Time.deltaTime;
    }
    private void Attack()
    {
        anim.SetTrigger("attack");
        cooldownTimer = 0;

        fireballs[0].transform.position = firePoint.position;
        fireballs[0].GetComponent<Ammo>().SetDirection(Mathf.Sign(transform.localScale.x));
    }

}

Ammo脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ammo : MonoBehaviour
{
    [SerializeField] private float speed;
    private bool hit;
    private Animator anim;
    private BoxCollider2D boxCollider;
    private float direction;

    private void Awake()
    {
        anim.GetComponent<Animator>();
        boxCollider = GetComponent<BoxCollider2D>();
    }

    private void Update()
    {
        if (hit) return;
        float movementSpeed = speed * Time.deltaTime * direction;
        transform.Translate(movementSpeed, 0, 0);

    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        hit = true;
        boxCollider.enabled = false;
        anim.SetTrigger("explode");
    }
    public void SetDirection(float _direction)
    {
        direction = _direction;
        gameObject.SetActive(true);
        hit = false;
        boxCollider.enabled = true;

        float localScaleX = transform.localScale.x;
        if (Mathf.Sign(localScaleX) != _direction)
            localScaleX = -localScaleX;

        transform.localScale = new Vector3(localScaleX, transform.localScale.y, transform.localScale.z);
    }
    private void Deactivate()
    {
        gameObject.SetActive(false);
    }
}

组件配置说明

  • Ammo组件:已挂载Ammo脚本,设置了speed参数,包含Animator和BoxCollider2D组件
  • PlayerAttack组件:已挂载PlayerAttack脚本,配置了attackCooldown参数,指定了firePoint,并给fireballs数组赋值

异常原因及解决方法

  • Ammo脚本Animator赋值错误:
    代码中Awake()方法里anim.GetComponent<Animator>()未将获取到的Animator组件赋值给anim变量,导致anim始终为null,触发explode动画时抛出异常。
    修复:将代码改为anim = GetComponent<Animator>();

  • PlayerAttack脚本中PlayerControllert拼写错误:
    变量playerMovement的类型写成了PlayerControllert(多了一个t),若你的玩家控制脚本实际类名为PlayerController,则GetComponent<PlayerControllert>()会返回null,后续若使用该变量会触发异常。
    修复:将类型改为正确的PlayerController(确保与你的玩家控制脚本类名一致)

  • fireballs数组未正确赋值:
    若Inspector中fireballs数组为空或索引0的元素未指定,Attack()方法中访问fireballs[0]会抛出空引用异常。
    修复:在PlayerAttack组件的Inspector面板中,给fireballs数组添加已挂载Ammo脚本的炮弹预制体

  • firePoint未正确赋值:
    若Inspector中未指定firePoint,Attack()方法中访问firePoint.position会抛出空引用异常。
    修复:在PlayerAttack组件的Inspector面板中,将场景中的发射点Transform拖入firePoint字段

  • Animator组件缺失或参数错误:
    若Player或Ammo对象未挂载Animator组件,或Animator控制器中未包含attack/explode触发参数,调用SetTrigger时会触发异常。
    修复:确保对应对象挂载Animator组件,且Animator控制器中存在对应的触发参数

内容的提问来源于stack exchange,提问作者squeezed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 04:07:06