xlua框架解析以及demo展示(二),主要是c#调用lua里的公共函数,以及lua调用c#和unity周期函数和组件

(一)c#调用lua里的公共函数
(1)调用lua中无参无返回值的全局函数
第一种方式,用c#中的Action来映射lua中没有参数,没有返回值的全局函数:
lua代码:


function funGlo1()
print("This is a global function in lua")
end

function funGlo3(x,y)
    print(x+y)
    return x+y
end

c#中的代码

using UnityEngine;
using XLua;
using System;//action时要用

public class CSCallLuaGlobalFunciton : MonoBehaviour
{
    // Start is called before the first frame update
   
    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        //action适合lua中没有参数,也没有返回值的全局函数
        Action act = luaEnv.Global.Get<Action>("funGlo1");
        act();

    }

   
}

第二种方式,用自己定义的委托,映射lua中的无参数,无返回值的全局函数
lua代码同上
c#代码:

using UnityEngine;
using XLua;
using System;//action时要用

public class CSCallLuaGlobalFunciton : MonoBehaviour
{
   
    //自己定义的delegat,映射lua中没有参数和返回值的全局函数,这里的delegate是小写
    public delegate void MyDelegate1();

    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        //用自己定义的delegat,映射lua中没有参数和返回值的全局函数
        MyDelegate1 d = luaEnv.Global.Get<MyDelegate1>("funGlo1");
        d();

    }

   
}

(2)用自定义delegate调用lua中有参数和返回值的全局函数
c#代码

using UnityEngine;
using XLua;
using System;//action时要用

public class CSCallLuaGlobalFunciton : MonoBehaviour
{

    //自己定义的delegate,映射lua中有参数有返回值的全局函数
    [CSharpCallLua]//注意这种delegate要加标签
    public delegate int MyDelegate3(int x,int y);

    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        // //自己定义的delegate,映射lua中有参数有返回值的全局函数
        MyDelegate3 d3= luaEnv.Global.Get<MyDelegate3>("funGlo3");
        int result3 = d3(1, 3);
        print(result3);
    }

ps:这个加标签的情况可以xlua配置文件中改,在xlua例子文件夹中的examplegenconfig文件中修改注册。

(3)用自定义delegate,映射lua中有参数,有多个返回值的lua全局函数
lua代码:

function funGlo4(x,y)
    return x*y,x*x,y*y
 end

c#代码

using UnityEngine;
using XLua;
using System;//action时要用

public class CSCallLuaGlobalFunciton : MonoBehaviour
{
 
    [CSharpCallLua]//还是要加标签 
    public delegate int MyDelegate4(int x, int y,out int result2,out int result3);

    void Start()
    {
        LuaEnv luaEnv = new LuaEnv();
        luaEnv.DoString("require 'luaFile'");
        //自定义的delegate,映射lua中有参数,有多个返回值的全局函数
        MyDelegate4 d4 = luaEnv.Global.Get<MyDelegate4>("funGlo4");
        int result2=0;
        int result3=0;
        int result1 = d4(1, 3, out result2, out result3);
        print(result1+","+result2+","+result3);
     
    }
}

(二)lua调用c#
(1)简单的调用
格式都是: CS.命名空间.函数名
lua代码

--lua控制csharp
--CS.UnityEngine.Debug.Log("lua call csharp");--lua调用unity中的debug
--local go=CS.UnityEngine.GameObject();--lua创建游戏物体
--go.name="root"

--lua查找游戏对象,获取对象上的游戏组件
--一个小技巧,可以在c#中写好代码,再黏贴到lua文件中,修改好
--local go1=CS.UnityEngine.GameObject.Find("Directional Light")
--local light=go1:GetComponent("Light")
--CS.UnityEngine.GameObject.Destroy(light)

--lua加载游戏预制体
--local CSUnity=CS.UnityEngine
--local cubeprefab=CSUnity.Resources.Load("CubePrefab")
--local go2=CSUnity.GameObject.Instantiate(cubeprefab)

(2)lua实现uinty周期函数
科普:
描述:
代表lua全局环境的LuaTable
void Tick()
描述:
清除Lua的未手动释放的LuaBase(比如,LuaTable, LuaFunction),以及其它一些事情。
需要定期调用,比如在MonoBehaviour的Update中调用。
lua代码



print("lua call test")

function luaAwake()
    print("This is luaAwake()")
end

function luaStart()
    print("This is luaStart()")
end

function luaUpdate()
    print("This is luaUpdate()")
end

function luaDestroy()
    print("This is luaDestroy()")
end

c#代码

using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{

    public TextAsset luafile;
    LuaTable runTable;
    Action _luaStart;
    Action _luaAwake;
    Action _luaUpdate;
    Action _luaDestroy;

    LuaEnv luaEnv;
    private void Awake()
    {
      
        luaEnv = new LuaEnv();
        runTable=luaEnv.NewTable();
        LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
        metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
        runTable.SetMetaTable(metaTable);//把元表放入普通表中
        metaTable.Dispose();//可以销毁元表
        //这句可以解释成这个文件的内容,包含在这个表里
        luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring

        _luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
        _luaStart = runTable.Get<Action>("luaStart");
        _luaUpdate = runTable.Get<Action>("luaUpdate");
        _luaDestroy = runTable.Get<Action>("luaDestroy");
        if (_luaAwake != null)
        {
            _luaAwake();
        }

    }

    void Start()
    {
        if (_luaStart != null)
            _luaStart();
       
    }

    // Update is called once per frame
    private void Update()
    {
        luaEnv.Tick();
        if (_luaUpdate != null)
            _luaUpdate();
    }

    private void OnDestroy()
    {
        if (_luaDestroy != null)
            _luaDestroy();
    }
}

(3)lua实现this指针
举个例子:在lua脚本中实现物体旋转
场景设置
在这里插入图片描述
c#代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{

    public TextAsset luafile;
    LuaTable runTable;
    Action _luaStart;
    Action _luaAwake;
    Action _luaUpdate;
    Action _luaDestroy;

    // Start is called before the first frame update

    LuaEnv luaEnv;
    private void Awake()
    {
      
        luaEnv = new LuaEnv();
        runTable=luaEnv.NewTable();
        LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
        metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
        runTable.SetMetaTable(metaTable);//把元表放入普通表中
        metaTable.Dispose();//可以销毁元表

        //把当前对象的指针传到表中,方便lua调用
        runTable.Set("self", this);

        //这句可以解释成这个文件的内容,包含在这个表里
        luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring
        _luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
        _luaStart = runTable.Get<Action>("luaStart");
        _luaUpdate = runTable.Get<Action>("luaUpdate");
        _luaDestroy = runTable.Get<Action>("luaDestroy");
        if (_luaAwake != null)
        {
            _luaAwake();
        }
        else
        {
            Debug.Log("没有找到该函数");
        }



    }

    void Start()
    {
        if (_luaStart != null)
            _luaStart();
       
    }

    // Update is called once per frame
    private void Update()
    {
        luaEnv.Tick();
        if (_luaUpdate != null)
            _luaUpdate();
    }

    private void OnDestroy()
    {
        if (_luaDestroy != null)
            _luaDestroy();
        else
        {
            Debug.Log("没有找到luadestroy");
        }
    }
}

lua脚本

--用全局变量代替命名空间
cc=CS.UnityEngine
print("lua call test")

function luaAwake()
    print("This is luaAwake()")
end

function luaStart()
    print("This is luaStart()")
end

function luaUpdate()
    print("This is luaUpdate()")
    --实现物体自转
    local v=cc.Vector3.up*30.0*cc.Time.deltaTime
    --这里要注意是冒号
    self.transform:Rotate(v)
end

function luaDestroy()
    print("This is luaDestroy()")
end

(4)lua操控游戏物体
流程:c#建立个类,有物体名字和游戏物体,然后将游戏物体放入list【类名】的列表中,然后以key,value的方式将游戏物体添加进lua的table里,再在lua文件中使用
场景布置
在这里插入图片描述
在这里插入图片描述
c#代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using System;//action要用的命名空间
public class LuaCallStart : MonoBehaviour
{

    public TextAsset luafile;
    LuaTable runTable;
    Action _luaStart;
    Action _luaAwake;
    Action _luaUpdate;
    Action _luaDestroy;
	//用来装游戏物体的list
    public List<GameObjectsClass> goList;

    // Start is called before the first frame update

    LuaEnv luaEnv;
    private void Awake()
    {
      
        luaEnv = new LuaEnv();
        runTable=luaEnv.NewTable();
        LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
        metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
        runTable.SetMetaTable(metaTable);//把元表放入普通表中
        metaTable.Dispose();//可以销毁元表

        //把当前对象的指针传到表中,方便lua调用
        runTable.Set("self", this);
        //把golist里的物体,添加到runTable表中
        for(int i = 0; i < goList.Count; i++)
        {
            runTable.Set(goList[i].name, goList[i].go);
        }

        //这句可以解释成这个文件的内容,包含在这个表里
        luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);//注意这里的写法有顺序,要先设置表,在来dostring
        _luaAwake = runTable.Get<Action>("luaAwake");//可以用表来查找全局函数了,因为其元表指向了全局变量
        _luaStart = runTable.Get<Action>("luaStart");
        _luaUpdate = runTable.Get<Action>("luaUpdate");
        _luaDestroy = runTable.Get<Action>("luaDestroy");
        if (_luaAwake != null)
        {
            _luaAwake();
        }
        else
        {
            Debug.Log("没有找到该函数");
        }



    }

    void Start()
    {
        if (_luaStart != null)
            _luaStart();
       
    }

    // Update is called once per frame
    private void Update()
    {
        luaEnv.Tick();
        if (_luaUpdate != null)
            _luaUpdate();
    }

    private void OnDestroy()
    {
        if (_luaDestroy != null)
            _luaDestroy();
        else
        {
            Debug.Log("没有找到luadestroy");
        }
    }
}

[Serializable]//序列化
//用来装游戏物体的类
public class GameObjectsClass  
{
    public string name;
    public GameObject go;
}

lua代码


cc=CS.UnityEngine
print("lua call test")

function luaAwake()
    print("This is luaAwake()")
end

function luaStart()
    print("This is luaStart()")
end

function luaUpdate()
    print("This is luaUpdate()")
    --实现物体自转
    local v=cc.Vector3.up*30.0*cc.Time.deltaTime
    self.transform:Rotate(v)
    --这里的名字要和设置进runtable表里的一致
    A1.transform.position=cc.Vector3(5,5,5)
    D1.transform.position=cc.Vector3(10,10,10)
end

function luaDestroy()
    print("This is luaDestroy()")
end

(5)lua控制ui事件
场景布置
在这里插入图片描述
在这里插入图片描述
ps:这个脚本挂在button组件下,所以this指向的事button

lua代码


cc=CS.UnityEngine
print("lua call test")

--控制button组件以及inputfield组件
self:GetComponent("Button").onClick:AddListener(
    function()
        print("lua control button ok")
        local i=login:GetComponent("InputField")
        if i.text~="" then
            print(i.text)
        else
            print("值不能为空")
        end

    end
)

c#代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using UnityEngine.UI;

public class LuaCallUI : MonoBehaviour
{
    public TextAsset luafile;
    LuaTable runTable;
    public List<GameObjectsClass> goList;
    LuaEnv luaEnv;

    private void Awake()
    {
        luaEnv = new LuaEnv();
        runTable = luaEnv.NewTable();
        LuaTable metaTable = luaEnv.NewTable(); //这是一个元表
        metaTable.Set("__index", luaEnv.Global);//让元表的查询全部指向文件中的公共变量
        runTable.SetMetaTable(metaTable);//把元表放入普通表中
        metaTable.Dispose();//可以销毁元表

        //这个脚本挂载的游戏对象为this,方便lua调用
        runTable.Set("self", this);
        //把golist里的物体,添加到runTable表中
        for (int i = 0; i < goList.Count; i++)
        {
            runTable.Set(goList[i].name, goList[i].go);
        }

        //这句可以解释成这个文件的内容,包含在这个表里
        luaEnv.DoString(luafile.text, "luaFile2.lua", runTable);
    }


}

ps:点号,冒号的总结,对象的方法用冒号,别的用点号?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值