浅析一个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函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...
随机推荐
- 利用Python操作MySQL数据库
前言 在工作中,我们需要经常对数据库进行操作,比如 Oracle.MySQL.SQL Sever 等,今天我们就学习如何利用Python来操作 MySQL 数据库. 本人环境:Python 3.7.0 ...
- Pytorch Autograd (自动求导机制)
Pytorch Autograd (自动求导机制) Introduce Pytorch Autograd库 (自动求导机制) 是训练神经网络时,反向误差传播(BP)算法的核心. 本文通过logisti ...
- Python接口自动化测试框架: pytest+allure+jsonpath+requests+excel实现的接口自动化测试框架(学习成果)
废话 最近在自己学习接口自动化测试,这里也算是完成一个小的成果,欢迎大家交流指出不合适的地方,源码在文末 问题 整体代码结构优化未实现,导致最终测试时间变长,其他工具单接口测试只需要39ms,该框架中 ...
- python 把多个list合并为dataframe并输出到csv文件
import pandas as pd a = [1,2,3] b = ['a','b','c'] test = pd.DataFrame({'a_list':a,'b_list':b}) 将两个列表 ...
- alpine 容器优化
摘要:alpine容器一直是使用得比较多的,而且也是官方推荐使用的.但是官方的容器会有一些不方便的地方,比如安装软件, 时区不同等. 所以本文旨在完成一个alpine容器通用模板作为记录 # 导入 ...
- idea的yml文件不识别问题
idea的yml文件不识别问题 每次当我写yml文件的时候都没有提示,而且yml文件的图标竟然是txt的图标 然后我上网查阅,发现在下面这里竟然连yml文件都无法添加设置为配置文件 然后我使用网上的下 ...
- 2020-07-07:mysql如何实现跨库join查询?
福哥答案2020-07-07: 1.同服务跨库.表名称带上库名.SELECT * FROM 数据库名称1.表名称 JOIN 数据库名称2.表名称 ON 数据库名称1.表名称.tid = 数据库名称2. ...
- C#LeetCode刷题之#226-翻转二叉树(Invert Binary Tree)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4080 访问. 翻转一棵二叉树. 输入: 4 / \ ...
- C#LeetCode刷题之#409-最长回文串(Longest Palindrome)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3788 访问. 给定一个包含大写字母和小写字母的字符串,找到通过这 ...
- Idea + maven搭建SSM框架
1.打开idea,新建项目,选择maven骨架,然后填写包名和项目名称,一直下一步. 接着下一步,配置项目的maven环境 创建完成之后,如下图:(上边的项目名字只是例子,具体的以自己搭建的项目名为准 ...