Skip to content

当不存在Component时GetComponent返回值在编辑器与构建包中不一致 #1036

@ps5mh

Description

@ps5mh

测试环境:xLua-v2.1.15, 官方Unity2019.4.40

测试代码:

using System;
using UnityEngine;
using XLua;

namespace XLuaTest
{
    public class Helloworld : MonoBehaviour
    {
        public Helloworld thiz;
        // Use this for initialization
        void Start()
        {
            var c = GetComponent<Canvas>();
            try
            {
                Debug.Log(c.enabled);
            }
            catch (MissingComponentException e)
            {
                // !! UNITY EDITOR ONLY !!
                // There is no 'Canvas' attached to the "Test" game object, but a script is trying to access it.
                // You probably need to add a Canvas to the game object "Test".Or your script needs to check if the component is attached before using it.
                Debug.LogError("In Edior:" + e);
            }
            catch (NullReferenceException e)
            {
                Debug.LogError("In Build:" + e);
            }
            LuaEnv luaenv = new LuaEnv();
            bool APPLYFIX = false; // my solution
            if (APPLYFIX)
            {
                luaenv.DoString(@"
local U = CS.UnityEngine;
if U.Application.isEditor then
    local function xlua_patch_member_func(type, funcName, genWrap)
        print('patch ' .. type.FullName .. ':' .. funcName)
        local r = debug.getregistry()
        local meta = r[type.FullName]
        -- @see xlua.c obj_indexer, upval1: instance indexer
        local _, objIndexer = debug.getupvalue(meta.__index, 1)
        objIndexer[funcName] = genWrap(objIndexer[funcName])
    end
    xlua_patch_member_func(typeof(U.GameObject), 'GetComponent', function(original)
        return function(...)
            local r = original(...)
            if r ~= nil and r:Equals(nil) then
                return nil
            end
            return r
        end
    end)
    xlua_patch_member_func(typeof(U.Object), 'GetComponent', function(original)
        return function(...)
            local r = original(...)
            if r ~= nil and r:Equals(nil) then
                return nil
            end
            return r
        end
    end)
end");
            }
            luaenv.DoString(@"
local U = CS.UnityEngine;
local go = U.GameObject.Find('Main Camera');
local c = go:GetComponent(typeof(U.Canvas)); -- go dees not have Canvas component
print(c == nil) -- print false in editor, true in build

c = go:AddComponent(typeof(U.Canvas));
print(c == nil) -- print false, definitely
U.GameObject.DestroyImmediate(c);
c = go:GetComponent(typeof(U.Canvas))
print(c == nil) -- print false in editor, true in build

local thiz = go:GetComponent(typeof(CS.XLuaTest.Helloworld));
U.GameObject.DestroyImmediate(thiz);
print(thiz.thiz == nil) -- print false, it's ok, destroyed, but valid userdata object
");
            luaenv.Dispose();
        }
    }
}

执行结果:

编辑器中打印false, 构建包中打印true

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions