Unity如何检测精灵丢失或为空?

4
我想检测图像雪碧是否为“缺失”或“无”
  1. 输入图像描述
  2. 输入图像描述
当我获取这个雪碧图时,它们都像这样得到了“null”,那么我如何知道它是“缺失”还是“无”? 输入图像描述 PS:我想知道它是缺少还是没有,对我来说是不同的情况。

如果 whatever.sprite == null,Unity 会重写 == 运算符和 Equals 方法,以使您更轻松地进行操作。 - Draco18s no longer trusts SE
@Draco18s 是的,我知道,我想知道它是缺失还是没有,这对我来说是不同的情况。 - TimChang
@TimChang,missing 和 none 是两个不同的概念 - 它们都会被解析为 null。 - Bejasc
你能提供更多关于为什么需要这个工作的上下文吗?因为我们可能能够提供与您当前所做的不同的替代建议。 - WQYeo
3
@Kaynn,我为我的UI编写单元测试,所以我想检查所有缺失的内容,如果精灵为空,那就没问题了,因为有时我们会在运行时设置精灵,但是缺失的精灵显然是错误的。 - TimChang
1个回答

11
Unity在尝试访问空引用时,会因不同原因抛出不同的异常!这也是为什么你应该强烈避免使用someObject == null检查的原因。Unity已经覆盖了类型Object(大多数Unity内置类型的母类)的== null行为,即使一个对象看起来是null,它仍然存储一些信息,比如刚才提到的它为什么是null的原因。

因此,你可以使用一个小“技巧”,只需尝试访问一个字段,并检查在try-catch块中确切得到了哪个异常:

public void CheckReference(Object reference)
{
    try
    {
        var blarf = reference.name;
    }
    catch (MissingReferenceException) // General Object like GameObject/Sprite etc
    {
        Debug.LogError("The provided reference is missing!");
    }
    catch (MissingComponentException) // Specific for objects of type Component
    {
        Debug.LogError("The provided reference is missing!");
    }
    catch (UnassignedReferenceException) // Specific for unassigned fields
    {
        Debug.LogWarning("The provided reference is null!");
    }
    catch (NullReferenceException) // Any other null reference like for local variables
    {
        Debug.LogWarning("The provided reference is null!");
    }
}

例子

public class Example : MonoBehaviour
{
    public Renderer renderer;
    public Collider collider;

    private void Awake()
    {
        renderer = GetComponent<Renderer>();
        Destroy(renderer);
    }

    private void Update()
    {
        if (!Input.GetKeyDown(KeyCode.Space)) return;

        CheckReference(renderer); // MissingComponentException
        CheckReference(collider); // UnassignedReferenceException

        Sprite sprite = null;

        CheckReference(sprite);   // NullReferenceException

        sprite = Sprite.Create(new Texture2D(1, 1), new Rect(0, 0, 1, 1), Vector2.zero);
        DestroyImmediate(sprite);
        CheckReference(sprite);   // MissingReferenceException
    }

    public void CheckReference(Object reference)
    {
        try
        {
            var blarf = reference.name;
        }
        catch (MissingReferenceException) // General Object like GameObject/Sprite etc
        {
            Debug.LogError("The provided reference is missing!");
        }
        catch (MissingComponentException) // Specific for objects of type Component
        {
            Debug.LogError("The provided reference is missing!");
        }
        catch (UnassignedReferenceException) // Specific for unassigned fields
        {
            Debug.LogWarning("The provided reference is null!");
        }
        catch (NullReferenceException) // Any other null reference like for local variables
        {
            Debug.LogWarning("The provided reference is null!");
        }
    }
}

enter image description here


那太聪明了。 - alynurly
这是一个很好的解决方案,我认为它在过去对我起作用,但现在它不起作用了(Unity 2021.3.4)。您的测试脚本仍然按预期工作 - 在DestroyImmediate之后,我会收到有关sprite的MissingReferenceException。但是,如果我在编辑器中正常删除sprite,则无法正常工作。例如添加SpriteRenderer组件,分配Sprite,然后从项目中删除Sprite。编辑器字段显示为“缺失”而不是“无”,但我收到的是NullReferenceException而不是MissingReferenceException。 - eternal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接