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;
        }
相关推荐
牛哇网络工作室11 小时前
UnityHDRP写实数字人全流程基础5—语音输入和语音识别
android·unity·c#·游戏引擎·aigc·语音识别·xcode
ellis19701 天前
u3d插件xLua[九]例8 Hotfix
unity
淡海水1 天前
01-07-运行时-GC深度剖析-内存分配回收与结构选择
jvm·windows·unity·gc
优梦创客1 天前
游戏开发架构选型:第1篇|什么是架构?从进球事件看 MVC 的局限
unity·架构·游戏引擎·游戏开发
zhangphil2 天前
Unity3D(Unity)跨平台游戏引擎简介
unity
Madokaly2 天前
DOTween动画:TweenManager深度解析
unity
_ZHOURUI_H_3 天前
Unity TCP底层极限拆解:粘包、半包、CRC、序列号、双缓冲到底怎么一起工作的?
网络·网络协议·tcp/ip·游戏·unity·游戏引擎·游戏开发
KindSuper_liu3 天前
Unity 游戏网络基础:从 TCP、UDP 到 HTTP、TLS 与 Best HTTP
网络·游戏·unity
qq_170264753 天前
unity里GameObject和Texture的内存归属
java·unity·游戏引擎