xlua游戏热更新(C#访问lua)

xlua作为Unity资源热更新的重要解决方案api,在Tecent重多游戏中被采用,本文通过案例去讲解xlua代码结构层次。

csharp 复制代码
/*
 * Tencent is pleased to support the open source community by making xLua available.
 * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
 * http://opensource.org/licenses/MIT
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/

using UnityEngine;
using XLua;

namespace XLuaTest
{
    public class Helloworld : MonoBehaviour
    {
        // Use this for initialization
        void Start()
        {
            //创建xlua虚拟机
            LuaEnv luaenv = new LuaEnv();
            luaenv.DoString("print('hello xlua!')");
            luaenv.DoString("CS.UnityEngine.Debug.Log('hello world')");
            //释放资源
            luaenv.Dispose();
        }

        // Update is called once per frame
    }
}

加载lua文件

Resources.Load("xlua/xx.lua") 加载

创建Resources 目录下xx.lua.txt文件

csharp 复制代码
//创建xlua虚拟机【建议全局唯一】
LuaEnv luaenv = new LuaEnv();
//加载lua脚本资源
TextAsset textAsset = Resources.Load<TextAsset>("xlua/hello.lua");
luaenv.DoString(textAsset.ToString());

loader加载

csharp 复制代码
luaenv.DoString("require 'xlua/hello'"); //require + 'lua文件名称不加扩展名'
//require 实际上是逐个查找loader文件 是否存在指定文件

自定义loader

挨个查找loader,若某个loader返回了字节数组,那么便不继续查找了

csharp 复制代码
  //加载loader
            luaenv.AddLoader(Myloader);
            
            luaenv.DoString("require 'xlua/hello'");
            //挨个查找loader,若某个loader返回了字节数组,那么便不继续查找了
            //释放资源
            luaenv.Dispose();

		/// <summary>
        /// 自定义loader
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private byte[] Myloader(ref string filePath)
        {
            print(filePath);
            string s = "print(123)";
            return Encoding.UTF8.GetBytes(s);
        }

构建Assets/StreamingAssets文件夹

csharp 复制代码
  private byte[] Myloader(ref string filePath)
        {
            //print(filePath);
            string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt";
            return Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
        }

C#访问lua文件

全局变量

加载文件成功后,访问lua文件中的全局变量

--number 可以对应int float double

csharp 复制代码
           //通过luaenv 访问变量
            int integer_Lua = luaenv.Global.Get<int>("Integer");
            string name_Lua = luaenv.Global.Get<string>("Name");
            
            Debug.Log(integer_Lua + name_Lua);

csharp 复制代码
//lua文件中

person = {
    Name = "James",
    Sno = 23,
    
    eat = function()
        print("i'm eating!")
    end
    
}
//
//C#
class Person
        {
            public string _name;
            public int _sno;
        }
 Person luaPerson = luaenv.Global.Get<Person>("person");
            print(luaPerson._sno + ":" + luaPerson._name);

接口

csharp 复制代码
IPerson luaPerson = luaenv.Global.Get<IPerson>("person");
 print(luaPerson.sno + ":" + luaPerson.name);


[CSharpCallLua]
        interface IPerson
        {
            string name { get; set; }
            int sno { get; set; }
            void eat();
        }

字典

复制代码
dic = {
    china = 1,
    america = 2,
    uk  = 3,
}
csharp 复制代码
 //通过字典遍历
            Dictionary<string,int> dic =  luaenv.Global.Get<Dictionary<string, int>>("dic");
            foreach (var key in dic.Keys)
            {
                print(key + ":" + dic[key]);
            }

列表

复制代码
list = {'sdahjk',12,123,'12'}
csharp 复制代码
  //通过list访问
            List<object> list =  luaenv.Global.Get<List<object>>("list");
            foreach (var target in list)
            {
                print(target.ToString());
            }

再将上述数据通过List读取一次

LuaTable

csharp 复制代码
LuaTable table = luaenv.Global.Get<LuaTable>("person");
            table.Get<string>("name");

函数

csharp 复制代码
 [CSharpCallLua]
        delegate int Add(int a, int b);

//函数
            Add add = luaenv.Global.Get<Add>("add");
            print(add(3,5));
            add = null;

lua多返回值通过,out 变量接受

复制代码
add = function(a,b)
    return a + b,a,b
end
csharp 复制代码
 delegate int Add2(int a, int b, out int resa, out int resb);

使用LuaFunction (性能差)

csharp 复制代码
LuaFunction add = luaenv.Global.Get<LuaFunction>("add");
            object[] objects = add.Call(3, 5);
            print(objects[0]);
相关推荐
合作小小程序员小小店6 小时前
桌面开发,在线%信息管理%系统,基于vs2022,c#,winform,sql server数据。
开发语言·数据库·sql·microsoft·c#
曹牧7 小时前
C#中的StartsWith
java·服务器·c#
时光追逐者7 小时前
分享5款.NET开源免费的Redis客户端组件库
数据库·redis·开源·c#·.net·.net core
Hacker_Fuchen7 小时前
Postman最被低估的功能,自动化接口测试效率简直无敌
自动化测试·软件测试·自动化·lua·postman
wuletaotao7 小时前
Postman使用教程
测试工具·lua·postman
小邓   ༽7 小时前
C语言课件(非常详细)
java·c语言·开发语言·python·eclipse·c#·c语言课件
睡前要喝豆奶粉7 小时前
EF Core动态sql
数据库·sql·c#·.netcore
故事不长丨7 小时前
C#委托的使用
c#·wpf·winfrom·委托·网站开发
网安墨雨7 小时前
【软件测试】Postman中变量的使用
自动化测试·软件测试·测试工具·lua·postman
未来之窗软件服务7 小时前
幽冥大陆(三十八)P50酒店门锁SDK C#仙盟插件——东方仙盟筑基期
开发语言·单片机·c#·东方仙盟·东方仙盟sdk·东方仙盟vos智能浏览器