本来C#中Vector3是数值类型的数据,所以理所当然认为在lua表中的Vector3数据被深拷贝的时候,拷贝的应该也是数值,然而有两个地方出人意外,让我吃了个小苦瓜!在这里记录一下加深印象。
以前用得没有问题的深拷贝方法如下:
_G. DeepCopy = function ( object)
local SearchTable = { }
local function Func ( object)
if type ( object) ~= "table" then
return object
end
if SearchTable[ object] then return lookupTable[ object] end
local NewTable = { }
SearchTable[ object] = NewTable
for k, v in pairs ( object) do
NewTable[ Func ( k) ] = Func ( v)
end
return setmetatable ( NewTable, getmetatable ( object) )
end
return Func ( object)
end
这个方法拷贝纯Lua里面的数据没有问题,但是如果Lua数据里面包含了Unity的Vector3类似的数据,那么就会出现问题了,通过打印知道,Vector3的数据在判断type(object)的时候,其类型值为userdata,这时候就直接执行了return object,将Vector3数据原本返回了,按理来说,Vector3在C#那边是值类型的数据,我们直接复制这个数据使用,在更改的时候不会对原本数据产生影响,但是结果却是影响了,这是一个坑。
所以我就对那一部分的类型判断增加了一种特殊的处理,增加了lua中的类型判断和对象类型判断,然后返回New的一个新数据:
_G. DeepCopy = function ( object)
local SearchTable = { }
local function Func ( object)
if type ( object) ~= "table" then
if type ( object) == "userdata" and object: GetType ( ) . Name == "Vector3" then
return CS. UnityEngine. Vector3 ( object. x, object. y, object. z) ;
end
return object
end
if SearchTable[ object] then return lookupTable[ object] end
local NewTable = { }
SearchTable[ object] = NewTable
for k, v in pairs ( object) do
NewTable[ Func ( k) ] = Func ( v)
end
return setmetatable ( NewTable, getmetatable ( object) )
end
return Func ( object)
end
然后即使有Vector3这一类数据的深拷贝也就没问题了。
疑问来了:居然如此,那在Lua这边,Vector3貌似就当成引用类型来使用了,可是我使用判断的时候,直接判断两个Vector3类型的数据是否相等的时候(vector3Data1 == vector3Data2),居然可以直接判断,结果没有任何问题,如果是引用类型的,这个就有点不符合逻辑了。最后我只能认为。对比的时候执行的代码是C#那边Vector3类型比对的重载方法。