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

FPS游戏拾取物体时设置localScale触发NullReferenceException错误

问题原因分析

你遇到的NullReferenceException是因为**PickupParent为null**,导致访问PickupParent.transform时触发空引用错误,具体诱因有两个:

  1. PickupParent赋值逻辑不可靠:你在Start()里通过PickupParent = transform.parent赋值,但如果挂载该脚本的GameObject初始状态下没有父物体,transform.parent会直接返回null,导致PickupParent为空。
  2. 缩放对象逻辑错误:你修改的是脚本自身所在物体的transform.localScale,而非被拾取物体的缩放——这不仅违背你修复缩放问题的初衷,还会因为PickupParent为空直接触发报错。
修复步骤

1. 确保PickupParent正确赋值

既然你已经给PickupParent添加了[SerializeField]属性,直接在Unity Inspector面板中,将主相机下的空GameObject拖入该字段即可,这种手动赋值的方式比代码依赖物体父子结构更稳定。

如果坚持用代码赋值,必须先做空判断:

void Start()
{
    if(transform.parent != null)
    {
        PickupParent = transform.parent;
    }
    else
    {
        Debug.LogError("当前挂载脚本的物体没有父物体,请检查层级结构");
    }
}

2. 修正缩放逻辑

你需要修改的是被拾取物体的缩放,而非脚本自身物体的。将缩放代码替换为:

// 目标是修改拾取物体的localScale,而非当前脚本的transform
pickupRB.transform.localScale = new Vector3(
    1 / PickupParent.localScale.x, 
    1 / PickupParent.localScale.y, 
    1 / PickupParent.localScale.z
);

这样当物体成为PickupParent的子物体时,其localScale会抵消父物体的缩放影响,保持原始大小。

3. 添加空安全检查

在PickupObject()方法开头增加空判断,提前拦截错误:

public void PickupObject()
{
    if(lookObject == null) 
    {
        Debug.LogWarning("未瞄准任何可拾取物体");
        return;
    }
    if(PickupParent == null)
    {
        Debug.LogError("PickupParent未正确赋值,请检查");
        return;
    }

    // 原有拾取逻辑代码...
}

4. 修正语法错误(关键)

你贴出的代码存在严重语法问题:PickupObject()方法被嵌套在Update()方法内部,这是C#不允许的。必须将PickupObject()移到Update()外部,修正后的代码结构应为:

[SerializeField] private Transform PickupParent;
private PhysicsObjects physicsObject;
private GameObject currentlyPickedUpObject;
private Rigidbody pickupRB;

void Start()
{
    PickupParent = transform.parent; // 或使用Inspector手动赋值
}

void Update()
{
    // 这里编写Update周期的逻辑,比如检测拾取输入
}

public void PickupObject()
{
    // 所有拾取逻辑放在此处
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 14:45:40