xLua 随笔

一、纯lua相关问题

0. Lua 的 元表 元方法 和 opp的关系

Lua 学习元表,元方法_liaosheng:)-CSDN博客_lua 元方法

这个博客写的很详细了,多注意:元表的含义, 和__index这个元方法的含义;

Lua本没有面向对象,但是利用元表和__index的特效我们也可以实现面向对象。

BaseClass = { trans = nil }

function BaseClass:new() -- 基类构造函数
    local o = {}
    setmetatable(o, { __index = self })
    return o
end

-----------------------------------------------
ItemClass = BaseClass:new()

function ItemClass:Release()
    print("释放")
end

-----------------------------------------------
Fruit = ItemClass:new()

function Fruit:BeEaten()
    print("水果被吃")
end

-----------------------------------------------
function start()
    local f = Fruit:new()

    f:BeEaten()
    f:Release()
end

1. Lua 的 虚变量

“_”即为虚变量,用来承接一些多个返回值的方法中不被我们需要的返回值,

功能上可以理解为占位符,但是虚变量是有值的。

2. Lua 的 虚表(听上去和虚变量有关联,其实完全不是一个东西)

先大白话总结:

Lua有自己的GC机制,被引用的对象不会被GC回收,

但是被弱引用引用的对象可以被回收,虚表(也叫弱表)就是具有弱引用条目的表。

所以到底是什么呢:

虚表也是表,设置了元表,同时定义了__mode字段:

        例:

local x = {}
setmetatable( x, {__mode="v"} )

__mode字段取值可分为k / v / kv

k表示table的keys是weak的,可被回收;
v表示table的values是weak的,可被回收;
kv表示都weak,key和value中的一个被回收,那么kv键值对就被从表中移除。

二、xLua使用遇到问题

1. require的使用

官方示例中: local util = require 'xlua.util'

直接获取 Resources/xlua/util.lua 脚本,喔,原来 require 直接会从Resources下面找脚本???

那么如果想获取的脚本不在 Resources 目录下怎么办呢?

顺藤摸瓜,于是在官方示例里找到了这些:

                AddSearcher(StaticLuaCallbacks.LoadBuiltinLib, 2); // just after the preload searcher
                AddSearcher(StaticLuaCallbacks.LoadFromCustomLoaders, 3);
#if !XLUA_GENERAL
                AddSearcher(StaticLuaCallbacks.LoadFromResource, 4);
                AddSearcher(StaticLuaCallbacks.LoadFromStreamingAssetsPath, -1);
#endif

从这段代码就知道了:为什么可以从Resources下可以找到 你想要的脚本

internal static int LoadFromResource(RealStatePtr L)
        {
            try
            {
                string filename = LuaAPI.lua_tostring(L, 1).Replace('.', '/') + ".lua";

                // Load with Unity3D resources
                UnityEngine.TextAsset file = (UnityEngine.TextAsset)UnityEngine.Resources.Load(filename);
                if (file == null)
                {
                    LuaAPI.lua_pushstring(L, string.Format(
                        "\n\tno such resource '{0}'", filename));
                }
                else
                {
                    if (LuaAPI.xluaL_loadbuffer(L, file.bytes, file.bytes.Length, "@" + filename) != 0)
                    {
                        return LuaAPI.luaL_error(L, String.Format("error loading module {0} from resource, {1}",
                            LuaAPI.lua_tostring(L, 1), LuaAPI.lua_tostring(L, -1)));
                    }
                }

                return 1;
            }
            catch (System.Exception e)
            {
                return LuaAPI.luaL_error(L, "c# exception in LoadFromResource:" + e);
            }
        }

回到原本的问题,自定义添加require该怎么办呢?

看上面第一个代码块中四个 AddSearcher ,

第一个LoadBuiltinLib,推测是内置的函数blablabla的,有时间可以试试把它注释掉,康康哪些方法用不了了.... 噗

第三个第四个都眼熟,resources 和 streamingAssets。

还剩第二个LoadFromCustomLoaders,追进去!

internal static int LoadFromCustomLoaders(RealStatePtr L)
        {
            try
            {
                string filename = LuaAPI.lua_tostring(L, 1);

                LuaEnv self = ObjectTranslatorPool.Instance.Find(L).luaEnv;

                foreach (var loader in self.customLoaders)
                {
                    string real_file_path = filename;
                    byte[] bytes = loader(ref real_file_path);
                    if (bytes != null)
                    {
                        if (LuaAPI.xluaL_loadbuffer(L, bytes, bytes.Length, "@" + real_file_path) != 0)
                        {
                            return LuaAPI.luaL_error(L, String.Format("error loading module {0} from CustomLoader, {1}",
                                LuaAPI.lua_tostring(L, 1), LuaAPI.lua_tostring(L, -1)));
                        }
                        return 1;
                    }
                }
                LuaAPI.lua_pushstring(L, string.Format(
                    "\n\tno such file '{0}' in CustomLoaders!", filename));
                return 1;
            }
            catch (System.Exception e)
            {
                return LuaAPI.luaL_error(L, "c# exception in LoadFromCustomLoaders:" + e);
            }
        }

嗯,就是它了!customLoaders!

然后blablabla,就找到了这个AddLoader(CustomLoader xxx)这个方法。

传入的是一个 委托:

其定义为:public delegate byte[] CustomLoader(ref string filepath);

喔,在这里处理你传入的path和想要怎么处理,然后返回脚本的 byte[]

okay,搞定!

上官方示例:

LuaEnv luaenv = new LuaEnv();
#if UNITY_EDITOR
            luaenv.AddLoader(new SignatureLoader(PUBLIC_KEY, (ref string filepath) =>
            {
                filepath = Application.dataPath + "/XLua/Examples/10_SignatureLoader/" + filepath.Replace('.', '/') + ".lua";
                if (File.Exists(filepath))
                {
                    return File.ReadAllBytes(filepath);
                }
                else
                {
                    return null;
                }
            }));

----------------------------------------------------------------------------------------------------------------------------

好吧,我直接看了半天官方示例,但是没有提前看最开始的文档,我是xx....

文档上明明白白写着设置loader的方法,哈哈哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用XLua可以在Unity中实现Lua脚本的编写,同时也可以让Lua脚本与C#代码进行交互。 以下是基本的使用步骤: 1. 下载XLua插件并导入到Unity中。 2. 在Unity中创建一个新的Lua文件,编写Lua脚本代码。 3. 在C#代码中使用XLua的API来加载并运行Lua脚本,例如: ``` using XLua; public class LuaManager : MonoBehaviour { private LuaEnv luaEnv; void Awake() { luaEnv = new LuaEnv(); luaEnv.DoString("require 'main'"); // 加载并执行Lua脚本 } void Update() { luaEnv.Tick(); // 更新Lua环境 } void OnDestroy() { luaEnv.Dispose(); // 释放Lua环境 } } ``` 在上面的例子中,`Awake()`方法中创建了一个Lua环境,然后通过`DoString()`方法加载并执行了Lua脚本。`Update()`方法中每帧都调用了`Tick()`方法来更新Lua环境,`OnDestroy()`方法中释放了Lua环境。需要注意的是,在实际的项目中,可能需要更加复杂的逻辑和管理方式来处理Lua脚本的加载和运行。 4. 在Lua脚本中使用XLua提供的API来调用C#代码或者导出Lua模块,例如: ``` -- 导出一个Lua模块 local module = {} module.foo = function() print("Hello from Lua!") end return module -- 调用C#代码 local gameObject = CS.UnityEngine.GameObject("LuaObject") local transform = gameObject.transform transform.position = CS.UnityEngine.Vector3(1, 2, 3) ``` 在上面的例子中,导出了一个名为`module`的Lua模块,并定义了其中的一个函数`foo()`。同时,也调用了C#代码的API来创建了一个新的GameObject,并修改了它的Transform组件的位置。 XLua还提供了其他的功能,例如自定义导出规则、GC优化等。在使用XLua之前,建议先了解一些基本的Lua语法和C#与Lua交互的机制,以便更好地使用XLua

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值