本来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类型比对的重载方法。