在Lua端使用unity的一些类时会有一些比较大的性能消耗,比如我们常用的位置赋值操作
transform.position = CS.UnityEngine.Vector3(0,1,0);
如果进行性能测试会发现在性能消耗上需要十多毫秒,关于如何进行性能测试,可以参考官方文档《XLua性能分析工具》,后面也会有相关的文章。对于这个性能消耗,一个这么简单的操作,而且类似这样的赋值语句是一个很常用甚至会很频繁使用的,我们不能接受,所以我们要对其进行性能优化。
关于这个性能消耗问题的分析,可以参考文章《用好Lua+Unity,让性能飞起来——Lua与C#交互篇》,里面虽然是用ulua来进行分析,但是对xlua也有一定的分析意义。根据这份分析,我们发现其实性能消耗的问题主要是vector3,那么如果我们不用vector3呢,利用扩展方法,比如我们在c#端新增一个方法,然后将其导出
public static void SetXYZ(this Transform transform, float x, float y, float z)
{
Vector3 newPosition = new Vector3(x, y, z);
transform.position = newPosition;
}
我们在Lua端可以直接调用这个方法来进行赋值操作
transform:SetXYZ(0,1,0);
经过这样的改造后,我们在进行测试,我们发现性能上立马又了质的提升,总耗时只有1ms了,当然这个统计都是整数,也许不到1ms,这样就实现了我们的需求,提升了性能。
虽然上面的操作实现了我们的需求,但是有时候我们还希望其他的一些操作也能用lua来实现,以避免lua和c#的频繁交互,比如vector3.Distance,这个时候我们还是考虑重写Vector3类,那么一般需要重写哪些类呢,我们可以参考tolua框架,github地址,在这里我们能看到作者重写了好多类,我们可以参考作者的写法来写适合xlua的类。
这里提供一个Vector3的示例,大家可以参考然后依葫芦画瓢来重写其他的类。
--------------------------------------------------------------------------------
-- Copyright (c) 2015 , 蒙占志(topameng) topameng@gmail.com
-- All rights reserved.
-- Use, modification and distribution are subject to the "MIT License"
--------------------------------------------------------------------------------
local math = math
local acos = math.acos
local sqrt = math.sqrt
local max = math.max
local min = math.min
local clamp = Mathf.Clamp
local cos = math.cos
local sin = math.sin
local abs = math.abs
local sign = Mathf.Sign
local setmetatable = setmetatable
local rawset = rawset
local rawget = rawget
local type = type
local rad2Deg = 57.295779513082
local deg2Rad = 0.017453292519943
---instance fields
---@field public x System.Single
---@field public y System.Single
---@field public z System.Single
---static properties
---@field public zero Vector3
---@field public one Vector3
---@field public forward Vector3
---@field public back Vector3
---@field public up Vector3
---@field public down Vector3
---@field public left Vector3
---@field public right Vector3
---@class Vector3 : UnityEngine.Vector3
local Vector3 = {}
local _get = {}
local unity_vector3 = CS.UnityEngine.Vector3
Vector3.__index = function(t,k)
local var = rawget(Vector3, k)
if var ~= nil then
return var
end
var = rawget(_get, k)
if var ~= nil then
return var(t)
end
return rawget(unity_vector3, k)
end
function Vector3.New(x, y, z)
local t = {x = x or 0, y = y or 0, z = z or 0}
setmetatable(t, Vector3)
return t
end
local _new = Vector3.New
Vector3.__call = function(t,x,y,z)
error("不要使用unity的构造函数,使用重写的Lua类通过New来实例化\n");
local t = {x &