关于unity的NullReferenceException和missingGameObject

NullReferenceException可以说是unity里最常见的报错,他的意思是空指针异常,一般就是引用的东西是null了,造成错误。
而偶尔也会见到 missingGameObject,报错信息一般是 gameobject XXX已经被销毁了,但是你仍然去访问它 ,这个意思。我一直不太清楚这俩有什么明显的区别,今天在改bug的时候开了空工程做了个实验:

public class ceshi : MonoBehaviour
{
    
    public GameObject go;
    public Transform tf;
    public ldkkk script;
  
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.D))
        {
            Destroy(go);
            Debug.LogError("Go");
            Debug.LogError(go == null);

            Debug.LogError("TF");
            Debug.LogError(tf == null);

            Debug.LogError("script");
            Debug.LogError(script == null);
            script.Print();

        }
       
    }
}

随便写了个测试脚本 随便放在场景中一个物体上,按下D键就去删除另一个物体

待删除的物体叫willDestroy,上边也挂一个脚本:

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

public class ldkkk : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public void Print()
    {
        Debug.LogError("我是挂载一个被干掉了的Gameobject上的脚本,我要发声!我要借尸还魂!");
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

然后把willDestroy以及他的脚本都拖到manager上,运行:
按下D键位:
在这里插入图片描述

结果是这样,gameObject transform script都不为空,且脚本上的函数也顺利执行了,想了下,想起来unity销毁物体的机制是下一帧才会销毁,所以这同一帧就会是这样的结果。
那简单改下代码, 再测试类执行后 先按D再按P

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

public class ceshi : MonoBehaviour
{
    
    public GameObject go;
    public Transform tf;
    public ldkkk script;
  
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.D))
        {
            Destroy(go);
            Debug.LogError("Go");
            Debug.LogError(go == null);

            Debug.LogError("TF");
            Debug.LogError(tf == null);

            Debug.LogError("script");
            Debug.LogError(script == null);
            script.Print();

        }
        //先按下D  之后再按P
        if (Input.GetKeyDown(KeyCode.P))
        {
            
            Debug.LogError("Go");
            Debug.LogError(go == null);

            Debug.LogError("TF");
            Debug.LogError(tf == null);

            Debug.LogError("script");
            Debug.LogError(script == null);
            script.Print();

        }
    }
}

结果就是这样
在这里插入图片描述
最让我觉得奇怪的是按下P后 gameobject和transform都是null了 但是这个函数却可以输出出来,我以为会直接报空指针异常,看来monoBehaviour得脚本没我想象的那么简单,在gameobject销毁后,如果其他地方持有这个脚本的引用,仍然可以做某些操作。
但是 此时如果你在用此脚本引用去调用gameobject,那就会报错missingGamobject
比如我把借尸还魂函数加一句:

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

public class ldkkk : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }
    public void Print()
    {
        Debug.LogError("我是挂载一个被干掉了的Gameobject上的脚本,我要发声!我要借尸还魂!");
        Debug.LogError(gameObject == null);
    }
    // Update is called once per frame
    void Update()
    {
        
    }
}

运行,就会这样:
在这里插入图片描述
大概的区别就是这样,我也不知道理解的对不对,反正之前我是觉得:
如果 XXX.func(); 若XXX是null了 那么一定会报错nullReference 今天这个操作让我知道了不一定,(= = 真是做了这么久还是这么菜的我

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值