u3d插件xLua[十] lua侧判空问题

讲解xLua中lua侧判空问题,这点挺重要的,面试中问xLua问题大概率会问

一.代码展示

下面代码关键位置都有注释

cs 复制代码
using UnityEngine;
using XLua;

namespace XLuaTest
{
    // 扩展:走 UnityEngine.Object 重载的 ==,用于识别 Destroy 后的"假 null"
    [LuaCallCSharp]
    [ReflectionUse]
    public static class UnityEngineObjectExtention
    {
        public static bool IsNull(this UnityEngine.Object o)
        {
            return o == null;
        }
    }

    public class HotfixTest : MonoBehaviour
    {
        public GameObject obj;
        LuaEnv luaenv = new LuaEnv();

        void OnGUI()
        {
            if (GUI.Button(new Rect(10, 10, 420, 80), "Destroy后对比 C#/Lua 判空"))
            {
                if (obj == null)
                {
                    Debug.LogWarning("请先在 Inspector 给 obj 赋值一个 GameObject");
                    return;
                }

                // 立即销毁,便于同帧对比(Destroy 会拖到帧末才真正销毁)
                DestroyImmediate(obj);

                // C#:== 为 true,但引用往往还在(假 null)
                // → true:走 UnityEngine.Object 重载的 ==,已销毁就算"空"
                Debug.Log("[C#] obj == null = " + (obj == null));
                
                // → true:UnityEngine.Object.Equals 与重载 == 一致,已销毁则视为与 null 相等
                Debug.Log("[C#] Equals(null, obj) = " + obj.Equals(null));

                // → false:不走重载,只比引用;变量里对象还在,不是真正的 null
                Debug.Log("[C#] ReferenceEquals(null, obj) = " + ReferenceEquals(null, obj));

                // Lua:== nil 不可靠,IsNull / Equals(nil) 才正确
                luaenv.Global.Set("host", this);
                luaenv.DoString(@"
                    local o = host.obj
                    -- → false:userdata 还在,Lua 的 == nil 认不出 Unity 假 null
                    print('[Lua] o == nil      =', o == nil)

                    -- → true:Equals 会走到 C#/Unity 判空,已销毁则为 true(o 为真 nil 时跳过调用)
                    print('[Lua] o:Equals(nil) =', o ~= nil and o:Equals(nil))

                    -- → true:扩展内部是 o == null,与 C# 的 obj == null 一致
                    print('[Lua] o:IsNull()    =', o:IsNull())


                    print('结论: Destroy 后不要只用 == nil,应使用 IsNull() 或 Equals(nil)')
                ");
            }

            string chHint = @"Inspector 指定 obj 后点按钮。对比 Destroy 后 C#/Lua 判空差异。IsNull 需先 XLua > Generate Code。";
            GUIStyle style = GUI.skin.textArea;
            style.normal.textColor = Color.red;
            style.fontSize = 16;
            GUI.TextArea(new Rect(10, 100, 500, 220), chHint, style);
        }
    }
}

二.Demo演示

三.结论

1.当调用DestroyImmediate(obj)销毁对象后,C#侧走obj == null会走重载函数 与 obj.Equals(null)都为true,走的是判断对象是否实际销毁的逻辑

2.ReferenceEquals(null, obj)为false,执行的是引用检测,不看有没有Destroy

3.Lua侧的o == nil为false,也是引用判断

4.Lua侧可以用o ~= nil and o:Equals(nil),返回true

5.可以写个IsNull然后在lua侧用o:IsNull(),返回true

cs 复制代码
        public static bool IsNull(this UnityEngine.Object o)
        {
            return o == null;
        }
相关推荐
谢斯1 天前
[unity]如何在unity中添加newtonsoft-json
unity·json·游戏引擎
天人合一peng1 天前
Unity标记固定颜色及投影标记
unity
云雨巫山2 天前
Unity 游戏开发性能优化全景手册
unity·智能手机·性能优化·游戏引擎
maybeyaluokenai2 天前
unity build in渲染管线概述
unity·图形渲染
云雨巫山2 天前
Unity 性能优化 · 图解全景手册
unity·性能优化·游戏引擎
Madokaly2 天前
DOTween的Vector3Plugin
unity
一梭键盘任平生3 天前
Shader入门笔记2
unity
点心的游戏开发世界3 天前
Unity C# 脚本学习笔记:命名空间与 using
学习·unity·c#
点心的游戏开发世界3 天前
Unity C# 脚本学习笔记:泛型
学习·unity·c#
微三云生态系统架构师-彭丹4 天前
任务卷轴积分系统架构设计:从任务状态机到合规风控的完整实现
unity·系统架构·游戏引擎