【Unity】(土方法+插件方法)如何解决空引用异常NullReferenceException

文章介绍了Unity中常见的运行时错误——空引用异常,提供了调试的四个步骤,并通过两个示例说明如何找到并解决此类问题。强调了培养独立调试能力和避免过度依赖外部帮助的重要性,同时提到了代码分层和使用插件作为额外的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是空引用异常

对于新手来说,Unity 90%的运行时错误都是NullReferenceException,这里就不放chatGpt的废话了,其就是字面意思,因为各种各样的原因造成了没有引用任何东西的情况。

调试的4个步骤

  1. 找到报错位置
  2. 分析哪些造成对象可能为null的原因
  3. 找到这个出问题的对象(断点、Debug.Log(),Console.WriteLine()
  4. 根据你的判断,决定如何处理这个对象。

例子1:一般错误

public class TestNullRef : MonoBehaviour
{
    private object myObject;
    void Start()
    {
        Debug.Log(myObject);//null
        myObject.ToString();
    }
}

在这里插入图片描述

根据上面的报错提示,先找到错误的位置,接着理清问题后,就该如何规避了:

  • 设个条件判断
  • 让类实例,从而实现分配
void Start(){
    myObject=new TestObject();
    Debug.Log(myObject);
    myObject.ToString();
}

private class TestObject{}

在这里插入图片描述

例子2:移动物体

一开始我先不设变量的值。

在这里插入图片描述

//代码无误的
public class MoveToTarget : MonoBehaviour
{
    [SerializeField] private Transform targetTransform;
    void Update()
    {
        Vector3 moveDir = (targetTransform.position - transform.position).normalized;
        float moveSpeed = 1f;
        transform.position += moveDir * moveSpeed * Time.deltaTime;
        //朝相反的方向移动,远离
        //targetTransform.position += moveDir * moveSpeed * Time.deltaTime;
    }
}

报错:未获取变量。

在这里插入图片描述

如果去掉[SerializeField]改为

private Transform targetTransform;

在这里插入图片描述

那么,我们想解决问题,先找到错误的位置了,使用Debug.Log()查找

void Update()
{
    Debug.Log(targetTransform);
    Debug.Log(transform);
    Vector3 moveDir = (targetTransform.position - transform.position).normalized;
    float moveSpeed = 1f;
    transform.position += moveDir * moveSpeed * Time.deltaTime;
}

在这里插入图片描述

无论是上述哪个错误,就是没写targetTransform变量的值,补上相应的GameObject就好了。

请添加图片描述

我们除了解决这个特定的问题,我们还可以获得什么?

其实存在很多原因造成空引用异常,比如找不到你设置的变量(当然也可能你没设),或者是局部变量与全局变量有冲突等等。

所以我们更应该要培养自己debug的能力,也不要太过依赖chatGpt,因为它有时挺不靠谱的。

额外的方法

  1. 如果是抄别人的教程和代码,遇到null情况,可以选择重启Unity再次运行游戏即可,因为别人都敢出教程了,基本不太可能遇到问题。
  2. 我写有限状态机时,选择把游戏对象的数据与逻辑进行分层,当inspector显示数据信息,我又运行游戏时,也会报这个错误,总之有些空错误不是自己的问题。

插件方法

https://assetstore.unity.com/packages/tools/game-toolkits/missing-reference-finder-257205

### 解决 UnityNullReferenceException 异常 当 `NullReferenceException` 发生于 `TextMeshProUGUI.UpdateMeshPadding` 方法时,通常意味着尝试访问的对象为空。这可能是由于脚本执行顺序不当、组件丢失或其他初始化错误引起的。 #### 可能的原因分析 1. **对象未正确赋值** 如果在调用 `UpdateMeshPadding` 前,某些依赖项尚未被正确初始化,则可能导致此异常[^1]。 2. **资源加载失败** 若 TextMeshPro 组件所使用的字体或材质未能成功加载,也可能引发此类问题。 3. **场景切换过程中出现问题** 场景转换期间可能会导致一些临时性的 null 引用情况出现,尤其是在异步操作中。 #### 推荐解决方案 为了有效处理这个问题,可以采取以下几个措施: - **验证所有必需组件的存在** 确认 GameObject 上确实附加了必要的组件(如 Canvas, RectTransform),并且这些组件都处于激活状态。 - **调整脚本执行顺序** 使用 `[ExecuteAlways]` 或者通过 Project Settings -> Script Execution Order 来确保特定脚本先于其他脚本运行,从而减少因初始化时机不同而导致的空指针风险。 - **延迟初始化逻辑** 对于那些可能还未准备好立即使用的对象,在 Start() 函数内使用协程 (Coroutine),等待一段时间后再进行实际的操作,这样可以让系统有更多时间完成全部准备工作。 - **捕获并调试异常** 利用 try-catch 结构包裹潜在危险区域,并打印详细的堆栈跟踪信息以便更好地定位具体位置和原因。 ```csharp try { textMeshProComponent.UpdateMeshPadding(); } catch (System.NullReferenceException e) { Debug.LogError($"Error updating mesh padding: {e}"); } ``` 此外,还可以考虑升级到最新版的 Unity 和 TextMeshPro 插件,因为官方会不断修复已知 bug 并优化性能表现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值