FPS游戏拾取物体时设置localScale触发NullReferenceException错误
问题原因分析
你遇到的NullReferenceException是因为**PickupParent为null**,导致访问PickupParent.transform时触发空引用错误,具体诱因有两个:
PickupParent赋值逻辑不可靠:你在Start()里通过PickupParent = transform.parent赋值,但如果挂载该脚本的GameObject初始状态下没有父物体,transform.parent会直接返回null,导致PickupParent为空。- 缩放对象逻辑错误:你修改的是脚本自身所在物体的
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
相关产品推荐
相关产品推荐

