博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity3D热更新之LuaFramework篇[05]--Lua脚本调用c#以及如何在Lua中使用Dotween
阅读量:4590 次
发布时间:2019-06-09

本文共 10121 字,大约阅读时间需要 33 分钟。

 在上一篇文章  中,我对LuaBehaviour脚本进行了扩展,添加了两个新的UI监听方法,也提到最好能单写一个脚本处理此事。本篇文章就来继续这个工作。

 

从Lua中调用C#代码

1、创建UI监听脚本

 打开之前的工程,在Assets/LuaFrameworks/Scripts/Common下,创建一个UIEventEx.cs脚本,将LuaBehaviour.cs中的AddButtonClick以及AddInputFieldEndEditHandler方法迁移过来,并扩展了一些其它方法,代码如下:

1 using LuaInterface;  2 using System.Collections;  3 using System.Collections.Generic;  4 using UnityEngine;  5 using UnityEngine.EventSystems;  6 using UnityEngine.UI;  7   8 ///   9 /// 自定义的添加UI监听的方法,可以用lua中调用以做事件绑定 10 ///  11 public class UIEventEx { 12     //添加监听 13     public static void AddButtonClick(GameObject go, LuaFunction luafunc) 14     { 15         if (go == null || luafunc == null) 16             return; 17  18         Button btn = go.GetComponent
UIEventEx.cs

在Assets/LuaFrameworks/Scripts/Common下,创建一个EventsSupport.cs脚本,该脚本是一个实现了IPointerDownHandler, IPointerUpHandler等接口的类,用于在Lua中检测鼠标输入(鼠标点击,抬起、按下等功能),配合UIEventEx.cs中的AddPointerDownUpSupport方法使用。其代码如下:

1 using System; 2 using System.Collections; 3 using System.Collections.Generic; 4 using UnityEngine; 5 using UnityEngine.EventSystems; 6  7 /*  其它事件可根据需要在此类中实现 8     IPointerEnterHandler - OnPointerEnter - Called when a pointer enters the object 9     IPointerExitHandler - OnPointerExit - Called when a pointer exits the object10     IPointerDownHandler - OnPointerDown - Called when a pointer is pressed on the object11     IPointerUpHandler - OnPointerUp - Called when a pointer is released (called on the original the pressed object)12     IPointerClickHandler - OnPointerClick - Called when a pointer is pressed and released on the same object13     IInitializePotentialDragHandler - OnInitializePotentialDrag - Called when a drag target is found, can be used to initialise values14     IBeginDragHandler - OnBeginDrag - Called on the drag object when dragging is about to begin15     IDragHandler - OnDrag - Called on the drag object when a drag is happening16     IEndDragHandler - OnEndDrag - Called on the drag object when a drag finishes17     IDropHandler - OnDrop - Called on the object where a drag finishes18     IScrollHandler - OnScroll - Called when a mouse wheel scrolls19     IUpdateSelectedHandler - OnUpdateSelected - Called on the selected object each tick20     ISelectHandler - OnSelect - Called when the object becomes the selected object21     IDeselectHandler - OnDeselect - Called on the selected object becomes deselected22     IMoveHandler - OnMove - Called when a move event occurs (left, right, up, down, ect)23     ISubmitHandler - OnSubmit - Called when the submit button is pressed24     ICancelHandler - OnCancel - Called when the cancel button is pressed25  */26 27 /// 28 /// unity事件支持(本类用于实现Unity中的各种事件,借给Lua调用)29 /// 30 public class EventsSupport : MonoBehaviour, IPointerDownHandler, IPointerUpHandler31 {32     Action
onPointerDownHandler = null;33 Action
onPointerUpHandler = null;34 35 public void InitDownUpHandler (Action
downHandler, Action
upHandler)36 {37 onPointerDownHandler = downHandler;38 onPointerUpHandler = upHandler;39 }40 41 public void OnPointerDown(PointerEventData pointerEventData)42 {43 //Output the name of the GameObject that is being clicked44 //Debug.Log("[" + name + "] Game Object Click in Progress");45 46 if (onPointerDownHandler != null) {47 onPointerDownHandler(pointerEventData);48 }49 }50 51 //Detect if clicks are no longer registering52 public void OnPointerUp(PointerEventData pointerEventData)53 {54 //Debug.Log("[" + name + "] No longer being clicked");55 if (onPointerUpHandler != null)56 {57 onPointerUpHandler(pointerEventData);58 }59 }60 }
EventsSupport.cs

EventsSupport.cs脚本需要挂在待检测输入的Game Object上。

 

2、使用脚本

这里还是以上一篇文章写的登陆界面为例,之前我们是通过LuaBehaviour给Button、Toggle以及InputField添加的监听函数,现在将相应的用法直接替换掉。

替换前:

替换后:

 

然后运行,看是否生效。

......

运行结果,报错了,提示全局变量 UIEventEx为nil(就是这个变量不存在的意思)

  看来这样想当然的方法是行不通了,我们不能创建一个C#脚本,然后在Lua中直接使用它。

 

3、C#类导出

在上一步中,我们发现无法直接在Lua中使用创建的C#脚本。通过查阅资料了解到,对自定义的c#类,如果想在Lua中使用的话,需要做一个导出操作才行。

ToLua的官方git上也有相关的说明:

跟着说明操作:

1)找到Assets\LuaFramework\Editor\下的CustomSettings.cs脚本; 

2)在CustomSettings的60 行左右照例添加一个导出语句"_GT(typeof(UIEventEx)),";

 

3)点击Lua/Generate All菜单,等到日志打印 Generate LuaBinder over !字样时,表明Generate操作已经完成了。

此时查看Assets\LuaFramework\ToLua\Source\Generate,能找到一个叫UIEventExWrap的cs文件,这个就是UIEventEx的导出类。

 

4)重新运行Unity,已经不再报错了,点击Button、Toggle、在InputField中输入字符,功能都和之前使用LuaBehaviour时一致。

 

总结

如果想在Lua中使用自定义的c#类,需要4个步骤:

1)创建c#脚本;

2)在CustomSetting.cs中添加导出语句;

3)点击Lua/Generate All菜单;

4)在Lua中以全局变量的形式直接使用;

 

这里涉及的转化过程是这样的:

1)UIEventEx脚本通过Lua/Generate All菜单生成UIEventWrap脚本;

2)UIEventWrap脚本经过ToLua的作用,最终成为Lua中的一个全局变量UIEventEx

 

在之前的文章中我们曾直接使用Lua/Generate All菜单而未做解释,那么现在你应该明白它的做用是什么了。

至于ToLua怎么把一个XxxWrap转换为Lua中的全局变量,就不是本文能讲得清的了(你可以自己做弄清楚);

 

怎么在Lua中使用Dotween

Dotween作为一款非常优秀的缓动动画插件,基本上快成为Unity的标配了。而如果想把所有的UI逻辑全部Lua化,那么在Lua中使用Dotween就是必须的了。

根据前边的经验,Dotween相关的类对于ToLua来说,就是自定义类,想要在Lua中使用,就必须做导出操作。

那么就有以下步骤:

1)给项目导入一个Dotween插件;

2)导出Dotween相关类;

第二步就是要整理Dotween相关的类,然后一个个写导出语句,这不是一个简单的活儿。

不过不必担心,ToLua已经帮我们做好了。

打开Assets\LuaFramework\Editor\下的CustomSettings.cs脚本,在70~100行左右,能看到Dotween相关类的导出语句,不过由于未检测到USING_DOTWEENING宏定义的原因,这一段代码并未生效。

 3)使用宏定义USING_DOTWEENING

 一个简单的定义宏的办法是在脚本头部加入 #define USING_DOTWEENING语句,如下图

另外一个办法是在PlayerSettings的Scripting Define Symbols*下添加相应的宏,如下图: 

其中ASYNC_MOD是之前有的,两个宏之间用分号隔开,输入USING_DOTWEENING 要回车一次,让脚本重新编译。

这里使用第一种办法。

定义了宏之后,Dotween相关类的导出语句就生效了,然后要执行一次Lua/Generate All。

4)在Lua中作用Dotween

 以登陆界面的登陆按钮为例,在LoginPanel.lua脚本中添加如下的Dotween使用方法。 

然后运行,能看到动画已经生效了(移动及循环都没问题),不过最后的回调没执行。

看日志有一个报错,说的是TweenCallback未注册。这个就是OnComplete回调未执行的原因。

 TweenCallback是一个委托类型,根据此前了知识,委托类型也需要在CustomSetting中指定位置注册。

打开CustomSettings脚本,在40~50行左右的位置,添加TweenCallback的导出语句"_DT(typeof(DG.Tweening.TweenCallback)),",如下图所示:

之后重新执行Lua/Generate All菜单(如果有报错,可先执行一次Clear再执行Generate All)。

现在将循环次数改为1,重新运行。

能看到动画停止后,指定的日志已经输出。

在Lua中使用用Dotween,就是这样一个步骤。

 

 有一点要注意的是,在Lua中的代码提示是很不健全的,特别是在调用用C#脚本的时候。

这里写Dotween动画的代码就是全靠经验,如果不熟的话,也可以先用C#写一遍,再搬到Lua中改造。

 

怎么从C#中调用Lua脚本

文章的前半部分介绍了Lua中调用c#的方法,那么相应的如何从c#中调用Lua也有必要了解一下。

c#调用Lua是比较少的一个操作,基本上就在框架(LuaFramework)初始化的时候有用到。这里不做详细案例,只讲一下了解方式。

方式1:

ToLua的Examples, 03_CallLuaFunction,这个脚本详细讲述了c#调用Lua的过程。

方式2:

LuaFramework的LuaManager类,这个脚本里有详细的调用Main.Lua的过程。

 

 

后记 

一个疑问:

在写Lua的Dotween代码的时候,使用DOLocalMove、SetLoops和OnComplete都是用冒号:的方式,实际上这三个都是static方法,这有违于上一篇文章中总结的静态方法用点号,成员方法用冒号的规则。

暂不知道原因,如果你知道,还请留言指教。

 

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

疑问已解决,答案在1楼,感谢  大佬的解答

 

 

 

转载于:https://www.cnblogs.com/imteach/p/11026054.html

你可能感兴趣的文章
BZOJ1010: [HNOI2008]玩具装箱toy
查看>>
寻找素数对(hd1262)
查看>>
2015 HUAS Summer Contest#1~A
查看>>
KVM
查看>>
js点击某个图标或按钮弹出文件选择框
查看>>
python之路 jQuery学习笔记
查看>>
实训作业IO流
查看>>
2019-03-28 SQL Server char/nchar/nvarchar
查看>>
Windows Vista Business系统中成功安装的常用软件
查看>>
一个简单完整的promiseDemo
查看>>
电子商务网站的设计与实现(二):一期功能清单
查看>>
oracle中的事务
查看>>
JavaScript面向对象编程
查看>>
查看IIS-7.0中的进程PID
查看>>
关于Python的super用法研究
查看>>
训练1-A
查看>>
python三大器(装饰器/生成器/迭代器)
查看>>
ionic4+angular7+cordova上传图片
查看>>
[转]常用字符与ASCII代码对照表
查看>>
Oracle数据库提权(低权限提升至dba)
查看>>