|
1、作者教程:http://www.gad.qq.com/article/detail/24967
2、GitHub地址:https://github.com/Tencent/xLua 下载之后只需要把Plugins、XLua两个文件夹导入到Unity3D的Assets目录下就可以了。可以按照XLua文件夹下的XLua教程进行学习(如下图)
[img][/img]
[img][/img]
001-利用XLua在控制台输出Hello world- /*
- *Title:"XLua学习"项目开发
- */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XLua; //引入xLua命名空间
- public class HelloWorld : MonoBehaviour {
- private LuaEnv _luaenv; //推荐全局唯一
- void Start () {
- _luaenv = new LuaEnv(); //Lua运行环境
- //_luaenv.DoString("print('Hello world')"); //执行字符串形式的Lua代码
- _luaenv.DoString("CS.UnityEngine.Debug.Log('Hello world')"); //调用C#的Api
- }
-
- private void OnDestroy()
- {
- _luaenv.Dispose(); //释放lua运行环境
- }
- }
复制代码 002-读取Lua文件的代码并运行在Resources文件夹下新建一个Lua文件。如:HelloWorld.lua.txt(由于用Resources.Load<AssetText>()加载的是.txt类型的文件)- /*
- *Title:"XLua学习"项目开发
- *
- *Description:
- * 用于场景002
- * 读取Lua文件来执行Lua代码
- *Date:2017
- *
- *Version:0.1
- *
- *Modify Recoder:
- */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XLua;
- public class HelloWorldByFile : MonoBehaviour {
- LuaEnv _luaEnv;
- // Use this for initialization
- void Start () {
- _luaEnv = new LuaEnv();
- //方法1
- //TextAsset ta = Resources.Load<TextAsset>("HelloWorld.lua");//后缀自动添加.txt,因为是TextAsset类型
- //_luaEnv.DoString(ta.text); //读取文本的字符串并运行
- //方法2 用xLua自带的Loader加载和执行
- _luaEnv.DoString("require 'HelloWorld'"); //HelloWorld相当于HelloWorld.lua.txt,XLua的Loader会自动在Resources目录下加载
- }
- void OnDestroy()
- {
- _luaEnv.Dispose();
- }
- }
复制代码 003-自定义Loader,读取其他目录下的Lua文件- /*
- *Title:"XLua学习"项目开发
- *
- *Description:
- * 自定义Loader(加载器)
- *
- *Date:2017
- *
- *Version:0.1
- *
- *Modify Recoder:
- */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XLua;
- using System.IO;
- public class DefineLoader : MonoBehaviour {
- private LuaEnv _luaEnv;
- // Use this for initialization
- void Start () {
- _luaEnv = new LuaEnv();
- _luaEnv.AddLoader(MyLoader); //增加一个Loader
- _luaEnv.DoString("require 'DefineLoaderTest'");
- }
-
- //通过require加载一个文件的时候,会访问每一个Loader(先访问自定义的Loader后内置Loader)直到返回的不为空
- private byte[] MyLoader(ref string filePath)
- {
- Debug.Log(filePath); //这里filePath为DefineLoaderTest
- string absPath = Application.streamingAssetsPath + "/" + filePath + ".lua.txt"; //获取文件所在目录
- //把lua文件里面的字符串转换成字节数组返回,lua文件如果有中文需要把编码改为UTF8
- return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(absPath));
- }
- void OnDestroy()
- {
- _luaEnv.Dispose();
- }
- }
复制代码 004-通过C#调用Lua里面的全局变量、表(方法、变量)CSharpCallLua(lua代码):- intA = 100
- floB = 0.52
- isRun = true
- strName = 'Happy'
- person = {
- name = 'Jackey',age = 20,3,4.5,true,"stringgg",
- eat = function(self,foodName) --self代表当前对象,比C#对应的对象多一个参数
- print("正在吃:"..foodName)
- end
- }
- --[其他方式
- function person:eat(foodName) --用:的方式,会自动添加self
- print("正在吃:"..foodName)
- end
- function person.eat(self,foodName) --用.的方式,要自行添加
- print("正在吃:"..foodName)
- end
- --]
- function add(a,b) --全局函数
- print(a+b)
- return a+b,a,b
- end
复制代码 C#代码:- /*
- *Title:"XLua学习"项目开发
- *
- *Description:
- * C#访问Lua里面的全局变量
- *
- *Date:2017
- *
- *Version:0.1
- *
- *Modify Recoder:
- */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XLua;
- using System;
- public class CSharpCallLua : MonoBehaviour {
- private LuaEnv _env;
- // Use this for initialization
- void Start () {
- _env = new LuaEnv();
- _env.DoString("require 'CSharpCallLua'"); //加载并执行lua文件
- /*获取基本变量*/
- int intA = _env.Global.Get<int>("intA"); //获取Lua里面Int类型的全局变量
- Debug.Log(intA);
- float floB = _env.Global.Get<float>("floB"); //获取Lua里面float类型的全局变量
- Debug.Log(floB);
- bool isRun = _env.Global.Get<bool>("isRun"); //获取Lua里面bool类型的全局变量
- Debug.Log(isRun);
- string strName = _env.Global.Get<string>("strName"); //获取Lua里面string类型的全局变量
- Debug.Log(strName);
- /*获取table的方式一,通过类Class(Struct)*/
- Person p = _env.Global.Get<Person>("person"); //值拷贝,C#修改数据并不会同步到Lua,Lua修改也不影响C#
- Debug.Log(p.name);
- Debug.Log(p.age);
- /*获取table的方式二,通过接口interface(推荐)*/
- IPerson ip = _env.Global.Get<IPerson>("person"); //传引用,在C#修改会影响Lua里面的变量
- Debug.Log(ip.name);
- Debug.Log(ip.age);
- ip.eat("鸡腿"); //相当于ip.eat(ip,"鸡腿");
- /*获取table的方式三,通过键值对Dictionary、集合List(推荐)*/
- //Dictionary--只能映射table里面有键的元素
- Dictionary<string, object> dict = _env.Global.Get<Dictionary<string, object>>("person");
- foreach (string key in dict.Keys)
- {
- Debug.Log(key + '-' + dict[key]);
- }
- //List--只能映射table里面没有键的元素
- List<object> list = _env.Global.Get<List<object>>("person");
- foreach (object item in list)
- {
- Debug.Log(item);
- }
- /*通过LuaTable类(不推荐,性能比较差)*/
- LuaTable tab = _env.Global.Get<LuaTable>("person");
- print(tab.Get<string>("name"));
- print(tab.Get<int>("age"));
- print(tab.Length);
- /*访问Lua中的全局函数*/
- //方法一:映射到delegate
- Add act1 = _env.Global.Get<Add>("add");//属于命名空间System
- int resa, resb;
- print(act1(1,2,out resa,out resb));
- print(resa);
- print(resb);
- //方法二:映射到LuaFunction (不推荐)
- LuaFunction lf = _env.Global.Get<LuaFunction>("add");
- object[] os = lf.Call(3, 4);
- foreach (object item in os)
- {
- print(item);
- }
- }
- class Person
- {
- public string name;
- public int age;
- }
- [CSharpCallLua] //会为接口增加一些映射使用的代码
- interface IPerson
- {
- string name { get; set; } //必须添加get set属性
- int age { get; set; }
- void eat(string foodName);
- }
- [CSharpCallLua]
- delegate int Add(int a, int b,out int resa,out int reab); //lua全剧函数里面的第一个返回值会给C#的返回值,第二个返回值会给第一个out,第三个返回值会给第二个out
- void OnDestroy()
- {
- _env.Dispose();
- }
- }
复制代码 005-通过lua代码访问C#
LuaCallCSharp(lua代码):- CS.UnityEngine.GameObject("new by lua") --创建游戏物体(new对象)
- print(CS.UnityEngine.Time.deltaTime) --访问C#静态属性
- CS.UnityEngine.Time.timeScale = 0.5 --设置C#中的属性
- local camera = CS.UnityEngine.GameObject.Find('Main Camera') --用局部变量保存C#中的对象
- camera.name = "update by lua" --修改对象名称
- local gameObject = CS.UnityEngine.GameObject --用局部变量进行引用,可以节省性能,以及减少编码量
- local light = gameObject.Find('Directional Light')
- light.name = 'new light name'
- local cameraCam = camera:GetComponent('Camera') --获取Camera上的组件。推荐使用冒号调用成员函数,如果用点的话,第一个参数需要是当前对象
- gameObject.Destroy(cameraCam) --移除这个组件
复制代码 C#代码:- /*
- *Title:"XLua学习"项目开发
- *
- *Description:
- * 在lua里访问C#
- *
- *Date:2017
- *
- *Version:0.1
- *
- *Modify Recoder:
- */
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
- using XLua;
- public class LuaCallCSharp : MonoBehaviour {
- private LuaEnv _env;
- // Use this for initialization
- void Start()
- {
- _env = new LuaEnv();
- _env.DoString("require 'LuaCallCSharp'"); //加载并执行lua文件
- }
- void OnDestroy()
- {
- _env.Dispose();
- }
- }
复制代码 006-lua和C#中参数的对应(ref、out等关键字) Lua调用侧的参数处理规则:C#普通参数算一个输入形参,ref修饰的算一个输入形参,out不算,然后从左往右对应lua调用侧的实参列表。
Lua调用侧的返回值处理规则:C#函数的返回值(如果有的话)算一个返回值,out 算一个返回值,ref算一个返回值,然后从左往右对应lua的多返回值。
007-特性[LuaCallCSharp]和[CSharpCallLua]
在Lua获取或者调用C#的时候用[LuaCallCSharp]
在C#获取或者调用Lua的时候用[CSharpCallLua]
在枚举,委托,接口等前面加上[CSharpCallLua]或者[LuaCallCSharp]
008-lua中相当于C#中+=或-=的事件注册
例如testobj里有一个事件:public event Action TestEvent;
增加事件回调:testobj:TestEvent('+',lua_evnet_callback)
移除事件回调:testobj:TestEvent('-',lua_event_callback)
热更新大致流程
更新的东西有两部分:1、资源(Assetbundle) 2、lua代码 这两样东西放在服务器端,客户端连接服务器检查(MD5校验)是否有更新。服务器端使用一个文本文件存放所有Assetbundle和Lua的文件列表和对应的MD5值。客户端下载这个文本文件,客户端拿本地资源的MD5值对比服务器的MD5值,如果不一样则进行更新。这是其中一种方法。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|