Xlua支持通过子类对象访问父类的变量属性和方法
 
对于C#的ref,out参数的方法
当调用的时候:out类型的参数是不需要传递实参的,普通的参数和ref参数需要传递实参。
out,ref传出值通过lua函数的多返回值传出的,如果C#的函数有返回值,那么lua调用时的第一个返回值就是函数的返回值,之后依次是out和ref参数的传出值。
 
LuaCallCSharpFunction1.lua.txt
print('开始执行LuaCallCSharpFunction1.lua')

--先实例化一个类对象
d = CS.Lesson.D() --1、有一个参数
d:Func1("小明") --2、有一个out类型的参数,out类型的参数不需要传递实参
--out的传出的值是通过返回值的形式传出的
rt = d:Func2()
print("rt: ", rt) --3、有一个ref类型的参数
--ref修改的值也是通过返回值传出的
--ref需要传入实参
a = "lua"
rt = d:Func3(a)
print("a: ", a)
print("rt: ", rt) --4、一个out参数,一个ref参数
--out不需要实参,所以函数值需要一个实参
--一个out一个ref,所以函数有两个返回值
a, b = d:Func4("ref")
print("a: ", a)
print("b: ", b) --5、函数有返回值,一个out一个ref
a, b, c = d:Func5("ref")
print("a: ", a)
print("b: ", b)
print("c: ", c)
print('结束执行LuaCallCSharpFunction1.lua')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharpFunction1 : MonoBehaviour
{
LuaEnv luaEnv = new LuaEnv(); void Start()
{
luaEnv.DoString("require 'LuaCallCSharpFunction1' ");
} private void OnDestroy()
{
luaEnv.Dispose();
}
} namespace Lesson
{
public class D
{
public void Func1(string a)
{
Debug.Log("D -- Func1:" + a);
}
public void Func2(out string a)
{
a = "Func2";
Debug.Log("D -- Func2:" + a);
}
public void Func3(ref string a)
{
Debug.Log("D -- Func3:" + a);
a = "Func3";
}
public void Func4(out string a, ref string b)
{
a = "Func4";
Debug.Log("D -- Func4:" + a + "---" + b);
}
public bool Func5(out string a, ref string b)
{
a = "Func5";
Debug.Log("D -- Func5:" + a + "---" + b);
return true;
}
}
}
 
XLua支持C#函数的重载,但XLua并不是严格的支持C#函数的重载,因为Lua的number类型对应C#的int、float、double等类型。
 
XLua支持C#函数的可变参数方法,并且跟C#的调用相同。
 
XLua支持C#函数的默认参数
C#的默认参数必须放在非默认参数的后面,调用时,如果传入值那么就按照传入的值处理,如果未传入值,那么就按照默认的值处理。
C#的默认参数可以有多个,但是所有默认参数需要放在所有普通参数的后面。
 
LuaCallCSharpFunction2.lua.txt
print('开始执行LuaCallCSharpFunction1.lua')

--先实例化一个类对象
e = CS.Lesson.E() --不传入参数
e:Func1() --传入一个string类型的参数
e:Func1("小明") --传入一个number类型的参数
e:Func1()
e:Func1(1.2) --传入两个string类型的参数
e:Func1("小明", "小红") --支持可变参数
e:Func2("", "", "小明") --支持默认参数
e:Func3()
e:Func3() print('结束执行LuaCallCSharpFunction1.lua')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharpFunction2 : MonoBehaviour
{
LuaEnv luaEnv = new LuaEnv();
// Use this for initialization
void Start()
{
luaEnv.DoString("require 'LuaCallCSharpFunction2' ");
}
// Update is called once per frame
void Update()
{
}
private void OnDestroy()
{
luaEnv.Dispose();
}
}
namespace Lesson
{
public class E
{
//重载方法
public void Func1(){ Debug.Log("无参数的重载Func1");}
public void Func1(string str) { Debug.Log("有string参数的重载Func1"); }
public void Func1(int a) { Debug.Log("有int参数的重载Func1"); }
public void Func1(float a) { Debug.Log("有float参数的重载Func1"); }
public void Func1(string str1, string str2) { Debug.Log("有两个string参数的重载Func1"); } //可变参数
public void Func2(params string[] str_Arr)
{
foreach (var item in str_Arr)
{
Debug.Log("可变参数:" + item);
}
} //默认参数
public void Func3(string a = "小明") { Debug.Log("a: " + a); }
public void Func3(int b, string a = "小明", string c = "小红") { Debug.Log("b: " + b + "a: " + a + "c: " + c); }
}
}
XLua调用C#枚举
CS.命名空间.枚举名.枚举值 或 CS.枚举名.枚举值
 
Lua把字符串或数字转换成枚举
CS.命名空间.枚举名.__CastFrom(数字或字符串) 或 CS.枚举名.__CastFrom(数字或字符串)
注意:转换无限的数字不会报错,但是转换无效的字符串会报错。
 
LuaCallCSharpEnum.lua.txt
print('开始执行LuaCallCSharpEnum.lua')

--先实例化一个类对象
f = CS.Lesson.F() --参数是一个枚举类型
f:Func1(CS.LessonEnum.Type1.type2) --枚举与int或字符串相互转化
--自动转化
f:Func1()
--手动转化,数字的值可以任意,超过枚举项数,不会报错,字符串必须保证值存在
f:Func1(CS.LessonEnum.Type1.__CastFrom())
f:Func1(CS.LessonEnum.Type1.__CastFrom('小明')) print('结束执行LuaCallCSharpEnum.lua')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharpEnum : MonoBehaviour { LuaEnv luaEnv = new LuaEnv(); void Start()
{
luaEnv.DoString("require 'LuaCallCSharpEnum' ");
}
private void OnDestroy()
{
luaEnv.Dispose();
}
}
namespace Lesson
{
public class F
{
public void Func1(LessonEnum.Type1 type)
{
Debug.Log(type.ToString());
}
}
}
namespace LessonEnum
{
public enum Type1
{
type1,
type2,
type3,
小明,
}
}
 
Xlua是支持C#的委托,并且可以把Lua的方法添加到委托中去,但是Lua没有 += -=运算符。
对于一个空的委托,只能对其进行赋值a = b,不能a = a + b的形式添加
对于一个非空的委托,可以使用a = a + b(a = a - b)的形式去把b添加到a中
如果想把一个委托变为空。可以使用a = nil的方式
 
LuaCallCSharpDelegate.lua.txt
print('开始执行LuaCallCSharpDelegate.lua')

--lua对一个空委托进行赋值只能使用=,不能使用 a = a + b
CS.Lesson.G.del = CS.Lesson.G.Func1; --lua可以对一个非空委托使用 a = a + b 的形式,把b添加到a里去
CS.Lesson.G.del = CS.Lesson.G.del + CS.Lesson.G.Func1; --lua可以对一个非空委托使用 a = a - b 的形式,把b从到a里移除
CS.Lesson.G.del = CS.Lesson.G.del - CS.Lesson.G.Func1; func1 = function()
print("这是lua的方法")
end --把一个lua的方法,添加到C#的委托里
CS.Lesson.G.del = CS.Lesson.G.del + func1 --委托的调用
CS.Lesson.G.del() --非静态的委托
--先实例对象
g = CS.Lesson.G()
g.del1 = func1; --把委托变为空
g.del1 = nil
if g.del1 then
g.del1()
end print('结束执行LuaCallCSharpDelegate.lua')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharpDelegate : MonoBehaviour {
LuaEnv luaEnv = new LuaEnv();
// Use this for initialization
void Start()
{
luaEnv.DoString("require 'LuaCallCSharpDelegate' ");
}
private void OnDestroy()
{
luaEnv.Dispose();
}
}
namespace Lesson
{
public class G
{
public delegate void Del();
public static Del del;
public static void Func1()
{
Debug.Log("func1");
}
public Del del1;
}
}
静态委托:CS.命名空间.类名.委托变量名 或 CS.类名.委托变量名
成员委托:对象名.委托变量名
 
静态事件:CS.命名空间.类名.事件名('+或-', 想要添加到事件里的方法名)
成员事件:对象名:事件名('+或-', 方法名)
 
报错原因:对于委托和事件,在lua虚拟机释放之前需要C#的事件或委托需要清空
print('开始执行LuaCallCSharpEvent.lua')

--lua添加C#的事件的方法和C#是不一样的
--lua通过这种方式,把第二个参数添加到事件里
--静态事件:CS.命名空间.类名.事件名('+或-', 想要添加到事件里的方法名)
CS.Lesson.H.staticEvent('+', CS.Lesson.H.Func1) --lua是可以把lua的方法添加到事件里去的
func1 = function()
print("这是lua.func1的方法")
end CS.Lesson.H.staticEvent('+', func1) --调用
CS.Lesson.H.InvokeStaticEvent() --成员的事件
--实例化对象
h = CS.Lesson.H() --成员事件与静态事件的调用方式不一样
--成员事件:对象名:事件名('+或-', 方法名)
func2 = function()
print("这是lua.func2的方法") end
h:unStaticEvent('+', func2) --添加C#里的成员事件
func3 = function()
h:Func2()
end
h:unStaticEvent('+', func3) --调用
h:InvokeUnStaticEvent() --清空C#事件里的方法
CS.Lesson.H.staticEvent('-', CS.Lesson.H.Func1)
CS.Lesson.H.staticEvent('-', func1)
h:unStaticEvent('-', func2)
h:unStaticEvent('-', func3) print('结束执行LuaCallCSharpEvent.lua')
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class LuaCallCSharpEvent : MonoBehaviour { LuaEnv luaEnv = new LuaEnv(); void Start () {
luaEnv.DoString("require 'LuaCallCSharpEvent' ");
} private void OnDestroy()
{
luaEnv.Dispose();
}
} namespace Lesson
{
public class H
{
public delegate void Del();
public static event Del staticEvent;
public static void Func1()
{
Debug.Log("H Func1");
}
public static void InvokeStaticEvent()
{
if (staticEvent != null)
{
staticEvent();
}
} public event Del unStaticEvent;
public void Func2()
{
Debug.Log("H Func2");
}
public void InvokeUnStaticEvent()
{
if (unStaticEvent != null)
{
unStaticEvent();
}
}
}
}

UI案例

print('开始执行UI.lua')

Set = function(Self)
uiLua = Self
end Awake = function()
--获取Button组件,typeof(CS.UnityEngine.UI.Button)获取Button类型
button = uiLua.transform:Find("Button"):GetComponent(typeof(CS.UnityEngine.UI.Button));
--把lua的方法添加到button的事件中去
button.onClick:AddListener(ClickButton);
--获取Text组件
text = uiLua.transform:Find("Text"):GetComponent(typeof(CS.UnityEngine.UI.Text)); --获取Slider组件
slider = uiLua.transform:Find("Slider"):GetComponent(typeof(CS.UnityEngine.UI.Slider));
--给Slider添加事件
slider.onValueChanged:AddListener(SliderValueChanged);
--获取Image组件
image = uiLua.transform:Find("Image"):GetComponent(typeof(CS.UnityEngine.UI.Image));
end Destroy = function()
--把事件移除
button.onClick:RemoveListener(ClickButton);
button.onClick:Invoke()--删除瞬间,机器无法判断,需执行一次Invoke()
slider.onValueChanged:RemoveListener(SliderValueChanged);
slider.onValueChanged:Invoke()
end ClickButton = function()
text.text = "你好呀"
end SliderValueChanged = function(value)
image.color = CS.UnityEngine.Color(value, , );
end print('结束执行UI.lua')

在Editor里添加AddCSharpCallLua类,给系统的UnityAction类添加[XLua.CSharpCallLua]特性

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class AddCSharpCallLua
{
[XLua.CSharpCallLua]
public static List<System.Type> list = new List<System.Type>()
{
typeof(UnityEngine.Events.UnityAction<float>),
typeof(GameObject)
};
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
using UnityEngine.UI;
public class UILua : MonoBehaviour
{
private LuaEnv luaEnv = new LuaEnv();
[CSharpCallLua]
private delegate void Del(UILua ui);
private Del set;
[CSharpCallLua]
private delegate void Del1();
private Del1 awake;
private Del1 destroy;
// Use this for initialization
void Awake()
{
luaEnv.DoString("require 'UI' ");
set = luaEnv.Global.Get<Del>("Set");
set(this);
awake = luaEnv.Global.Get<Del1>("Awake");
if (awake != null)
{
awake();
}
destroy = luaEnv.Global.Get<Del1>("Destroy");
}
// Update is called once per frame
void OnDestroy()
{
if (destroy != null)
{
destroy();
}
//虚拟机释放之前所有的委托映射的方法,全部设为null
set = null;
awake = null;
destroy = null;
luaEnv.Dispose();
}
}

案列-MVC界面

MVC.lua.txt

print("开始执行MVC")

Set = function(Self)
panel = Self
end Awake = function()
--print("Awake")
skill1Button = panel.transform:Find("Buttons/Skill1Button"):GetComponent(typeof(CS.UnityEngine.UI.Button));
skill2Button = panel.transform:Find("Buttons/Skill2Button"):GetComponent(typeof(CS.UnityEngine.UI.Button)); hpText = panel.transform:Find("Hand/HPSlider/Text"):GetComponent(typeof(CS.UnityEngine.UI.Text));
hpSlider = panel.transform:Find("Hand/HPSlider"):GetComponent(typeof(CS.UnityEngine.UI.Slider));
skill1Button.onClick:AddListener(Skill1Click);
skill2Button.onClick:AddListener(Skill2Click);
--当数据改变时,需要更新界面,把更新界面的方法添加到PlayerData的事件里去
CS.PlayerData.Instance:updateEvent('+', UpdatePanel);
end Start = function()
--更新界面显示
UpdatePanel()
end Destroy = function()
--print("Destroy")
CS.PlayerData.Instance:updateEvent('-', UpdatePanel);
skill1Button.onClick:RemoveListener(Skill1Click);
skill1Button.onClick:Invoke()
skill2Button.onClick:RemoveListener(Skill2Click);
skill2Button.onClick:Invoke()
end UpdatePanel = function()
hpSlider.normalizedValue = CS.PlayerData.Instance.CurrentHP / CS.PlayerData.Instance.MaxHP;
hpText.text = CS.PlayerData.Instance.CurrentIntHP .. "/" .. CS.PlayerData.Instance.MaxIntHP;
end Skill1Click = function()
--print("Skill1Click");
CS.PlayerController.Instance:AddHPByGold();
end Skill2Click = function()
--print("Skill2Click");
CS.PlayerController.Instance:Hit(, CallBack);
end CallBack = function(str)
print("CallBack: ", str)
end
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using XLua;
public class PanelLua : MonoBehaviour {
private LuaEnv luaenv = new LuaEnv();
[CSharpCallLua]
private delegate void Del(PanelLua ui);
private Del set;
[CSharpCallLua]
private delegate void Del1();
private Del1 awake;
private Del1 destroy;
private Del1 start;
// Use this for initialization
void Awake () {
luaenv.DoString("require 'MVC'");
set = luaenv.Global.Get<Del>("Set");
set(this); awake = luaenv.Global.Get<Del1>("Awake");
if (awake != null)
{
awake();
}
start = luaenv.Global.Get<Del1>("Start");
destroy = luaenv.Global.Get<Del1>("Destroy");
}
private void Start()
{
if (start != null)
{
start();
}
}
private void OnDestroy()
{
if (destroy != null)
{
destroy();
}
//虚拟机释放之前所有的委托映射的方法,全部为null
set = null;
awake = null;
destroy = null;
start = null;
luaenv.Dispose();
}
}

Lua里面没有强制转化,Math.Ceil()向上取整也无法得到整数,可以使用如下方法在C#中返回整数

public float CurrentHP
{
get
{
return currentHP;
}
set
{
if (currentHP != value)
{
currentHP = value;
UpdatePanel();
}
}
} public int CurrentIntHP
{
get
{
return (int)currentHP;
}
}

Unity3D学习笔记(三十二):Xlua(2)的更多相关文章

  1. PHP学习笔记三十二【Exception】

    <?php // $fp=fopen("a.txt","r"); // echo "ok"; if(!file_exists(&quo ...

  2. Unity3D学习笔记(十二):2D模式和异步资源加载

    2D模式和3D模式区别:背景纯色,摄像机2D,没有深度轴 精灵图片设置 Normal map,法线贴图,更有立体感 Sprite (2D and UI),2D精灵贴图,有两种用途 1.当做UI贴图 2 ...

  3. ObjectARX学习笔记(三十二)----怎样设置AcDbMText对齐方式

    //_T("\\pxql;") 居左 //_T("\\pxqr;") 居右 //_T("\\pxqc;") 居中 //_T("\\ ...

  4. angular学习笔记(三十)-指令(2)-restrice,replace,template

    本篇主要讲解指令中的 restrict属性, replace属性, template属性 这三个属性 一. restrict: 字符串.定义指令在视图中的使用方式,一共有四种使用方式: 1. 元素: ...

  5. VSTO 学习笔记(十二)自定义公式与Ribbon

    原文:VSTO 学习笔记(十二)自定义公式与Ribbon 这几天工作中在开发一个Excel插件,包含自定义公式,根据条件从数据库中查询结果.这次我们来做一个简单的测试,达到类似的目的. 即在Excel ...

  6. angular学习笔记(三十)-指令(10)-require和controller

    本篇介绍指令的最后两个属性,require和controller 当一个指令需要和父元素指令进行通信的时候,它们就会用到这两个属性,什么意思还是要看栗子: html: <outer‐direct ...

  7. angular学习笔记(三十)-指令(7)-compile和link(2)

    继续上一篇:angular学习笔记(三十)-指令(7)-compile和link(1) 上一篇讲了compile函数的基本概念,接下来详细讲解compile和link的执行顺序. 看一段三个指令嵌套的 ...

  8. angular学习笔记(三十)-指令(7)-compile和link(1)

    这篇主要讲解指令中的compile,以及它和link的微妙的关系. link函数在之前已经讲过了,而compile函数,它和link函数是不能共存的,如果定义了compile属性又定义link属性,那 ...

  9. angular学习笔记(三十)-指令(6)-transclude()方法(又称linker()方法)-模拟ng-repeat指令

    在angular学习笔记(三十)-指令(4)-transclude文章的末尾提到了,如果在指令中需要反复使用被嵌套的那一坨,需要使用transclude()方法. 在angular学习笔记(三十)-指 ...

  10. angular学习笔记(三十)-指令(5)-link

    这篇主要介绍angular指令中的link属性: link:function(scope,iEle,iAttrs,ctrl,linker){ .... } link属性值为一个函数,这个函数有五个参数 ...

随机推荐

  1. Axis2之异步调用

    本章主要介绍axis2接口的异步调用方式. 一般情况下,我们使用同步方法(invokeBlocking)调用axis2接口,如果被调用的WebService方法长时间不返回,客户端将一直被阻塞,直到该 ...

  2. 自写Jquery插件 Datagrid

    原创文章,转载请注明出处,谢谢!https://www.cnblogs.com/GaoAnLee/p/9086582.html 废话不多说,先上个整体效果: html <div id='data ...

  3. The Little Prince-11/30

    The Little Prince-11/30 Today, I have a meeting in our department. I sincerely hope that all of my d ...

  4. 有登陆认证的情况下如何使用Wisdom RESTClient?

    访问REST API时,很多系统需要登陆认证,登陆成功以后才允许访问API.下面介绍一下有登陆认证情况下如何使用 Wisdom RESTClient测试API的方法. 方法很简单即在浏览器上成功登录系 ...

  5. Vue小案例 之 商品管理------删除商品与提示

    实现删除商品功能 根据索引来进行删除商品: 实现删除商品的HTML: <!--显示表格--> <div class="table-warp"> <di ...

  6. SaaS教父:我眼中最糟糕的9条SaaS建议(转)

    文章摘要:美国SaaS行业的教父级人物Jason Lemkin近日总结了在他眼里最糟糕的9条SaaS方面的建议,希望对SaaS行业的创业者有所启发. SaaS行业的创业者平时肯定会收到外界各种各样的建 ...

  7. Java 中断异常的正确处理方式

    处理InterruptedException 这个故事可能很熟悉:你正在写一个测试程序,你需要暂停某个线程一段时间,所以你调用 Thread.sleep().然后编译器或 IDE 就会抱怨说 Inte ...

  8. Docker 配置

    1. 网络 使用redsocks 需要配置 iptables -t nat -A PREROUTING -p tcp -j REDSOCKS 还需要使能 route_localnet # settin ...

  9. nagios监控oracle 表空间

    oracle表空间满的危害以及处理方式见我的博客链接https://www.cnblogs.com/-abm/p/9764803.html 除此之外我们还需要对表空间实时监控,这样就可以及时了解表空间 ...

  10. linux中没有tree命令,command not found,解决办法

    在有网络的情况下: 1.包管理器安装 centos 中用  yum -y install tree ubuntu 中用  apt-get install tree 当然如果需要权限不要忘了在前面加上 ...