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

为何带NavMeshAgent的射线点击移动脚本报NullReferenceException?

Unity NavMeshAgent引用为空排查(右键点击触发NullReferenceException)

问题概况

  • 运行教程复制的脚本时,右键点击控制物体移动,控制台持续抛出NullReferenceException: Object reference not set to an instance of an object。
  • 已确认挂载脚本的物体带有NavMeshAgent组件,但脚本无法获取到该组件的有效引用。
  • 核心诉求:排查组件存在但引用为空的原因,而非了解NullReferenceException的定义。
  • 补充:物体未按预期移动到点击点,已尝试序列化字段、this.gameObject.GetComponent<NavMeshAgent>(),问题未解决。

(图片说明:NavMeshAgent组件挂载在脚本所在的GameObject上)

原脚本代码

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

public class CharacterMovement : MonoBehaviour
{

    NavMeshAgent agent;

    public float rotateSpeedMovement;
    float rotateVelocity;

    // Start is called before the first frame update
    void Start()
    {
        agent = gameObject.GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
        //When pressing RMB
        if(Input.GetMouseButtonDown(1)){
            RaycastHit hit;
        
            //Checking if raycast has hit the navmesh system
            if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out hit,
            Mathf.Infinity)){

                //have the player move to the point
                agent.SetDestination(hit.point);

                //ROTATION
                Quaternion rotationToLookAt = Quaternion.LookRotation(hit.point - 
                transform.position);
                float rotationY = Mathf.SmoothDampAngle(transform.eulerAngles.y,
                rotationToLookAt.eulerAngles.y,
                ref rotateVelocity,
                rotateSpeedMovement * (Time.deltaTime * 5));

                transform.eulerAngles = new Vector3 (0,rotationY,0);
        
                }
            }
        }
    }

可能的原因及解决步骤

  1. 脚本执行顺序异常

    • 问题:CharacterMovement的Start()方法在NavMeshAgent组件初始化前执行,导致获取不到组件。
    • 解决:
      • 打开Project Settings > Script Execution Order,将CharacterMovement的执行顺序调整到NavMeshAgent之后;
      • 或者把获取组件的代码移到Awake()中(Awake在组件初始化阶段运行,比Start更早)。
  2. 组件/物体未激活

    • 问题:NavMeshAgent组件被禁用(面板复选框未勾选),或脚本所在物体在Start()执行时处于非激活状态(SetActive(false))。
    • 解决:确保NavMeshAgent组件启用,且物体在场景启动时为激活状态。
  3. 组件不在当前物体上

    • 问题:NavMeshAgent挂载在脚本物体的子物体上,而GetComponent<NavMeshAgent>()只会查找当前物体的组件。
    • 解决:
      • 改用GetComponentInChildren<NavMeshAgent>()(查找自身及所有子物体);
      • 或者将NavMeshAgent组件移到脚本所在的GameObject上。
  4. 脚本重复挂载到无组件物体

    • 问题:Hierarchy中有多个物体挂载了CharacterMovement脚本,其中某个物体没有NavMeshAgent,右键点击时触发了该脚本的代码。
    • 解决:
      • 在Hierarchy搜索CharacterMovement,确认所有挂载该脚本的物体都带有NavMeshAgent;
      • 给脚本添加[RequireComponent(typeof(NavMeshAgent))]特性,强制Unity自动为挂载脚本的物体添加NavMeshAgent(无组件时)。
  5. 组件被其他脚本销毁/移除

    • 问题:其他脚本在Start()之后、右键点击前,通过Destroy()或RemoveComponent()移除了NavMeshAgent。
    • 解决:搜索项目中操作NavMeshAgent的代码,排查是否有意外销毁/移除组件的逻辑。

优化后的示例脚本

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

// 强制挂载脚本时自动添加NavMeshAgent组件
[RequireComponent(typeof(NavMeshAgent))]
public class CharacterMovement : MonoBehaviour
{
    // 序列化字段允许直接在Inspector赋值,避免GetComponent的潜在问题
    [SerializeField]
    NavMeshAgent agent;

    public float rotateSpeedMovement;
    float rotateVelocity;

    void Awake()
    {
        // 双重保险:如果Inspector未赋值,自动获取组件
        if (agent == null)
        {
            agent = GetComponent<NavMeshAgent>();
        }
    }

    void Update()
    {
        if(Input.GetMouseButtonDown(1)){
            RaycastHit hit;
        
            if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition),out hit, Mathf.Infinity)){
                // 先判断agent是否为空,避免触发异常
                if (agent != null)
                {
                    agent.SetDestination(hit.point);
                }

                Quaternion rotationToLookAt = Quaternion.LookRotation(hit.point - transform.position);
                float rotationY = Mathf.SmoothDampAngle(transform.eulerAngles.y,
                rotationToLookAt.eulerAngles.y,
                ref rotateVelocity,
                rotateSpeedMovement * (Time.deltaTime * 5));

                transform.eulerAngles = new Vector3 (0,rotationY,0);
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 13:00:50