浅析一个lua文件窥slua工作机制
slua的东西不是几句话能讲得完,这里只说结论不说原因,原因有空写个Little Slua工程来解释,下面注释中有几个关键点:
LuaVar系列类:LuaFunction,LuaTable,LuaDelegate的使用,
类型表和实例表,__parent代表继承关系,存ud的表是弱表(可以用来缓存c#中引用类型的object对应ud)
import "UnityEngine" -- 是否导出了UnityEngine.GameObject类
if not UnityEngine.GameObject or not UnityEngine.UI then
error("Click Make/All to generate lua wrap file")
end -- cach一下,加速,这是lua的优化tip:cach函数,把变量都定义在函数开头等
local pi=math.pi
local class={} -- Circle.cs里先dofile把文件加载到global,然后通过luaState[key]把global的值压栈给c#使用
-- c#把入栈的luaState["main"]转换为LuaFunction,然后根据ref压栈并pcall之,得到classtable入栈,然后c#把此table转为LuaTable,
-- 就可以通过LuaTable里的ref访问register中的class这个实例数据了。
function main()
-- 先取得GameObject类型表,然后使用里面注册的Find函数(其实是lclosure),然后调用此lclosure, c#层对应的Find函数被调用,把找到的GameObject实例对象存入ObjectCach中
-- 同时作为ud压入栈,并设置GameObject实例表为该ud的元表,这样ud就可以使用GameObject实例表的Getcomponent函数(lclosure),
-- 同理的得到一个元表为UI.Slider实例表的ud,赋值给slider,counttxt类似
local slider = GameObject.Find("Canvas/Slider"):GetComponent(UI.Slider)
local counttxt = GameObject.Find("Canvas/Count"):GetComponent(UI.Text)
-- onValueChaned是UI.Slider实例表中注入的一个属性表,取属性会调用属性表里的第一个函数(lclosure),c#对应的get函数被调用,一个元表为SliderEvent实例表的ud入栈
-- 而SliderEvent实例表.__parent = UnityEvent_float实例表,后者注入了AddListenner函数(lclosure),调用它会调用c#对应函数,c#中把lua传过来的lfunction转为
-- LuaDelegate ld,接着实例化一个UnityAction<float>的委托,委托里会调用ld,并且委托会被Add到前面的ud在c#中的UnityEvent<float>实例中,
-- 这样,当c#的onValueChanged时就会调用该委托,进而调用ld,进而通过ld里的ref调用register里的lfunction,即下面那个函数
slider.onValueChanged:AddListener(
function(v)
class:init(v)
counttxt.text=string.format("cube:%d",v)
end
) -- 类型表__call会构造一个c#对象存入ObjectCach中,并作为ud入栈,且把对应的实例表设置为其元表
class.root = GameObject("root")
class.ftext = GameObject.Find("Canvas/Text"):GetComponent(UI.Text)
class.r=
class.cubes={}
class.t=
class.f=
class.framet=
class.max= class:init()
return class
end function class:init(count) for _,v in ipairs(self.cubes) do
GameObject.Destroy(v[])
end self.cubes={}
self.max=count or local P = Resources.Load("Particle System") self.colors={Color.red,Color.blue,Color.green,Color.cyan,Color.grey,Color.white,Color.yellow,Color.magenta,Color.black} -- slua对struct做了分离处理:对于Vector2,3,4,Color,Quantion等,比如把一个Vector2从c#传到lua,lua会生成一个Vector2类型的table存它并使用,
-- 把一个table传到c#,如果它是Vector2类型的,c#会生成一个Vector2存其数据,即slua通过数据拷贝来处理这类struct
-- 对于其他struct,slua当做ud来处理
for i=,self.max do
local cube = GameObject.CreatePrimitive(PrimitiveType.Cube)
cube.transform.position = Vector3(math.cos(i/self.max*pi*)*self.r,math.sin( i/self.max*pi*)*self.r,)
cube.transform:SetParent(self.root.transform)
local mat=cube:GetComponent(Renderer).material local box=cube:GetComponent(BoxCollider)
GameObject.Destroy(box) local p = GameObject.Instantiate(P,Vector3.zero,Quaternion.identity)
p.transform:SetParent( cube.transform ) mat.color=self.colors[math.random(#self.colors)]
table.insert(self.cubes,{cube,mat})
end
end function class:update() -- gc alloc is zero for i,v in ipairs(self.cubes) do
local offset = i%== and or -
local r = self.r+math.sin(Time.time)*offset
local angle= i%== and Time.time or -Time.time
local base=Vector3(math.cos(i/self.max*pi*+angle)*r,
math.sin(i/self.max*pi*+angle)*r,) v[].transform.position = base
--v[2].color=self.colors[math.random(#self.colors)]
end if not self.fogStart or self.t> then
self.fogStart=Time.time
self.bgCurrent = Camera.main.backgroundColor
self.bgColor=self.colors[math.random(#self.colors)]
end self.t=(Time.time-self.fogStart)/
Camera.main.backgroundColor = Color.Lerp(self.bgCurrent,self.bgColor,self.t) --calc fps
self.f=self.f+
self.framet=self.framet+Time.deltaTime
if self.framet>= then
self.ftext.text=string.format("fps:%d",self.f)
self.f=
self.framet=self.framet-
end
end
浅析一个lua文件窥slua工作机制的更多相关文章
- slua中,绑定lua文件到Monobehavior的一种方法
slua本身并不提供如何把一个lua文件绑定到一个预制中,就像一个普通的继承自monobehavior的自定义脚本那样,而tolua的框架却采用了拙劣的做法: public class LuaBeha ...
- Lua学习之加载其他lua文件
Lua 中提供了模块的概念,模块类似一个封装库或者 C++ 中的一个类,可以将公用的部分提到一个文件中,以 API 的形式供其他 lua 文件调用. Lua 中的模块其实就是包含变量.函数等已知元素组 ...
- MySQL Proxy和 Amoeba 工作机制浅析
MySQL Proxy处于客户端应用程序和MySQL服务器之间,通过截断.改变并转发客户端和后端数据库之间的通信来实现其功能,这和WinGate 之类的网络代理服务器的基本思想是一样的.代理服务器是和 ...
- 从一个简单的main方法执行谈谈JVM工作机制
本来JVM的工作原理浅到可以泛泛而谈,但如果真的想把JVM工作机制弄清楚,实在是很难,涉及到的知识领域太多.所以,本文通过简单的mian方法执行,浅谈JVM工作原理,看看JVM里面都发生了什么. 先上 ...
- Binder的工作机制浅析
在Android开发中,Binder主要用于Service中,包括AIDL和Messenger,其中Messenger的底层实现就是AIDL,所以我们这里通过AIDL来分析一下Binder的工作机制. ...
- Java I/O 的工作机制浅析
I/O 问题可以说是当今互联网 Web 应用中所面临的主要问题之一,因为当前在这个海量数据时代,数据在网络中随处流动.这个流动的过程中都涉及到 I/O 问题,可以说大部分 Web 应用系统的瓶颈都是 ...
- [原][资料整理][osg]osgDB文件读取插件,工作机制,支持格式,自定义插件
参考: osgPlugins相关 osg读取文件的原理(插件工作机制) 当使用osgDB读取文件时,会自动根据文件的扩展名来到插件目录中寻找相应的插件,来实现. 比如: osgviewer cow.o ...
- Java IO工作机制分析
Java的IO类都在java.io包下,这些类大致可分为以下4种: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...
- malloc 函数工作机制(转)
malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...
随机推荐
- 6月28日考试 题解(GCD约分+动态规划+树状数组二维偏序)
前言:考的一般般吧……T3暴力没打上来挺可惜的,到手的75分没了. ---------------------------------- T1 [JZOJ4745]看电影 Description 听说 ...
- spring boot中集成Redis
1 pom.xml文件中添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <arti ...
- Linux 中文编码
- java_Object类、日期时间类、System类、包装类
Object类 java.lang.Object 类是所有类的父类.它描述的所有方法子类都可以使用.在对象实例化的时候,最终找的父类就是Object. 如果一个类没有特别指定父类, 那么默认则继承自O ...
- CSS 学习第一天
css的三种引入方式: 1.内嵌:直接在标签中添加style属性 格式:<标签名 style="样式1:样式值1:样式2:样式值2"> 2.内联:在head标签中添加& ...
- bluecms v1.6 代码审计
0x01 使用seay源代码审计系统进行审计 扫描到了很多个可疑漏洞,不过工具都有一定的误报,下面我们就逐个进行验证 0x02 /ad_js.php SQL注入漏洞 查看源码,我们发现程序通过GET方 ...
- 后端程序员必备的 Linux 基础知识+常见命令(近万字总结)
大家好!我是 Guide 哥,Java 后端开发.一个会一点前端,喜欢烹饪的自由少年. 今天这篇文章中简单介绍一下一个 Java 程序员必知的 Linux 的一些概念以及常见命令. 如果文章有任何需要 ...
- 群晖系统设置链路聚合并配置静态IP的教程【江东网 JDX86.COM】
1.进入控制面板 > 网络 > 网络接口.请单击创建 > 创建 Bond 2.进入聚合配置向导,选择你想要的模式,这里有几种模式意思分别为: 自适应负载平衡: 此模式优化了 Syno ...
- 《Java从入门到失业》第二章:Java环境(四):IDE集成环境
2.4IDE集成环境 在掌握了编写.编译和运行Java程序的基本步骤以后,你肯定就在想,这太麻烦了,有没有更好的工具?当然有了,那就是IDE.IDE就是专业的集成开发环境(Integrated Dev ...
- 火题大战Vol.0 B 计数DP
火题大战Vol.0 B 题目描述 \(n\) 个沙茶,被编号 \(1\)~$ n$.排完队之后,每个沙茶希望,自己的相邻的两人只要无一个人的编号和自己的编号相差为 \(1\)(\(+1\) 或\(-1 ...