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;
        }
相关推荐
WarPigs16 小时前
Unity无法修改Assembly-CSharp.csproj错误
unity
FairGuard手游加固1 天前
手游加固怎么做?SO、IL2CPP、AssetBundle 与运行时保护详解
安全·游戏·unity
阿松爱学习2 天前
【Unity开发】监听Scene场景事件
unity·c#
xiaogai_gai3 天前
BOM 物料清单同步实战:金蝶云星空 → 四化智造 MES 修改场景深度拆解
unity·游戏引擎
淡海水3 天前
03-03-架构篇-SGen GC架构解析
unity·架构·c#·gc·sgen
萌萌的提莫队长4 天前
Unity相机捕捉,图像识别,抠像+合成
opencv·unity
mxwin4 天前
Unity Shader 光线追踪原理与实战案例
unity·游戏引擎
地狱为王5 天前
Unity使用DPDFNet实现实时语音增强(降噪)
unity·语音增强·降噪·dpdfnet
平行云PVT5 天前
国产信创实时云渲染解决方案:如何实现数字孪生与三维应用云化部署?
unity·webrtc·unreal engine·实时云渲染·国产信创·摩尔线程·砺算科技
夏炎黄5 天前
Terrain地形剪裁
unity