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;
        }
相关推荐
暴走约伯8 小时前
【VFX工具链源码拆解 09】终极工业化闭环:基于 ID 规则驱动的全自动场景建档、骨骼挂载与男转女场景迁移
unity·c#·游戏引擎·材质
寂寞的船1 天前
【Unity知识速递】第13期 Unity 内存泄漏排查实战:从 Memory Profiler 到 Lua 引用泄漏的生产级全链路诊断
unity·junit·c#·游戏引擎·lua
寂寞的船2 天前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
探求虚无3 天前
用 AI 在 Unity 里做一款 RTS:最难的不是生成代码,而是证明它真的能玩
人工智能·unity·游戏引擎
17岁的勇气4 天前
Unity Shader unity文档学习笔记(二十二):shader变体
笔记·学习·unity
寂寞的船5 天前
【Unity知识速递】第10期 Unity GC 零分配实战:从 UnityEngine.Pool 到手动 GC 控制的全链路优化
jvm·unity·c#·游戏引擎·lucene
寂寞的船7 天前
【Unity知识速递】第8期 IL2CPP 托管堆内存碎片与原生堆交互机制深度解析
unity·游戏引擎·交互
寂寞的船8 天前
【Unity知识速递】第5期 Unity 6.2 深度解析:AI Assistant 登场,World Space UI 与 Sentis 全面升级
人工智能·ui·unity
寂寞的船8 天前
【Unity知识速递】第4期 MCP for Unity:用 AI 自然语言控制编辑器
人工智能·unity·编辑器
淡海水8 天前
09-04-内存-Unity原生对象生命周期
unity·c#·游戏引擎·gc