UNITY3D在线更新之道-CSlight 使用总结

转自:http://blog.csdn.net/leonwei/article/details/39233775

最近做U3D的热更新,研究了各种方式无果后,最容易最先想到的方式就是利用c#的反射机制,动态加载代码,但是由于ios上aot的限制,导致ios上不能实现,最后 找到了cslight这个东西,可以在一定范围内动态编译执行cs代码。项目主页http://crazylights.cnblogs.com/  github 主页https://github.com/lightszero/CSLightStudio,这个cslight的作者还是很厉害的,利用这个东西成功的将项目中策划配表等容易经常变动的地方实现了动态编译执行,下面总结下对cslight的理解和使用心得。

1.首先cslight支持部分的c#代码,支持情况包括

项目 支持 不支持

注释

支持// 不支持 /* */
基本类型 支持int uint bool string float double 不支持byte char short 等,但可以扩展
变量和定义 同c#定义变量方式,先定义再使用,可以在定义同时赋值。

int i;
int j=0;
int k=i+1;
bool b1;
bool b2=true;
bool b3=false;

 
数学计算
同c#

支持

+ - * / %

五种数学计算

支持

+= -= /= *= %=

五种自运算

支持

++ --

两种自增运算,只支持变量在左侧

++i 不支持  i++ 支持

支持

> >= < <= != == && ||

八种逻辑运算

支持! 取反

支持三目运算?:

不支持位运算
循环 支持 for foreach while dowhile,支持continue,break,return

支持 if,可以if else嵌套

不支持switch goto
命名空间 可以写
Debug.Log();
不可以写
UnityEnging.Debug.Log();
C#Evil 头部可以写using
不支持
对象调用 注册了类型以后
new 支持
as 和 强制类型转换 支持
成员变量访问支持
成员函数调用支持
向类型注册事件代理支持
支持对象的[] index访问
静态支持
C#Evil 可以在脚本里编写class
脚本里编写的class 不能继承
数组 数组完整支持
支持
new int[3]
new int[]{1,2,3}
两种语法
任何类型数组都必须注册子类型和数组类型
泛型数组
作为类型支持
比如可以将List<int>
Dictionary<int,string> 注册成一个类型总体使用
 
泛型 支持

List<int> 作为一个类型不能有空格
例如 List  <  int > 就不认识了

 
委托 支持脚本编写函数注册给程序的委托接口
A.Test+=Func1;
A.SetTest(Func1);
两种形式
 
匿名函数 支持lambda表达式
可以给委托赋值
不支持 将lambda 表达式赋值给var变量
异常处理 支持  
继承 可以继承脚本中编写的interface,可以多继承 不支持class继承(是因为IOS 上aot的缘故)
get/set 只支持自动实现
int i
{
  get;
  set;
}
不支持编写get/set过程
     

2.基本的程序(cs)和脚本(cslight)之间的关系

3.使用步骤

1)new一个environment

CLS_Environment env=new CLS_Environment(this);

2)注册引擎的类给脚本,如env.RegType(new CSLE.RegHelper_Type(typeof(List<string>),"List<string>"));

3)编译脚本

Dictionary<string, IList<Token>> project = new Dictionary<string, IList<Token>>();
List<string> csPaths=new List<string>();
List<byte[]> bytes=new List<byte[]>();

for(int i=0;i<bytes.Count;i++){
IList<Token> tokens =env.ParserToken( CommonTool.Bytes2String(bytes[i],enc));
project.Add(csPaths[i],tokens);
}
env.Project_Compiler(project,true);

4)动态的执行代码

CLS_Content content=env.CreateContent();
IList<Token> runCodetokens = env.ParserToken(code);
CLS_Content.Value value=null;
try
{
ICLS_Expression expr = env.Expr_CompilerToken(runCodetokens);
value= env.Expr_Execute(expr, content);
}
catch (Exception err) {
Debug.LogError( string.Format("cs light run error dump:\n {0} {1}  
{2}",content.DumpValue(),content.DumpStack(null),err.ToString()));
}
return value;

C#Light能够有权限调用的类型需要提前注册

委托的注册稍微不太一样

env.RegDeleType(new CSLE.RegHelper_DeleAction("Action"));

调试错误

1.打Log进行判断

2.只需要在运行脚本时try一下,出错以后用content.DumpValue 可以Dump出脚本堆栈上的变量值

content.DumpStack 可以Dump出脚本执行堆栈

再加上异常本身反馈的信息

时间: 2024-10-14 23:21:09

UNITY3D在线更新之道-CSlight 使用总结的相关文章

Unity3D脚本学习——运行时类

AssetBundle 类,继承自Object.AssetBundles让你通过WWW类流式加载额外的资源并在运行时实例化它们.AssetBundles通过BuildPipeline.BuildAssetBundle创建. 参见:WWW.assetBundle ,Loading Resources at Runtime ,BuildPipeline.BuildPlayer function Start () { var www = new WWW ("http://myserver/myBund

【Unity3D】使用MD5值,确保本地Sqlite数据库内容没有被篡改

Sqlite的应用场景 在判断是否使用存储格式为Sqlite模式的标准,我们的标准是内容只读.也就是说,除非发布者修改Sqlite内容,玩家只有读取的权限. 换个角度说,Sqlite里面的数据都是游戏基础配置数据,比如游戏的关卡(不包括玩家取得的成就).怪物的血量.装备的模板数据 对于如何使用Sqlite,请参考我的另外一篇文章<Unity本地数据存储---Sqlite和JSON> 问题重现 OK,既然我们选择了Sqlite作为存储手段之一,那么我们也嘚重视起安全性. 以android而言,我

UNITY3d在移动设备上的一些优化实战(一)-概述

项目进入了中期之后,就需要对程序在移动设备上的表现做分析评估和针对性的优化了,首先前期做优化,很多瓶颈没表现出来,能做的东西不多,而且很多指标会凭预想,如果太后期做优化又会太晚,到时发现一些问题改起来返工量就有太大.前一阵子花了大量时间从 cpu gpu 内存 启动时间 到发热量对项目做了一翻大规模的体检和优化,效果还是显著的,在这里做个笔记,以后开发项目时可以作为经验和提前关注 1.项目情况:笔者所在项目是一个非常重度的手游,甚至开始就是瞄着端游做的,3D世界,2.5D视角,RPG,即使战斗,

Unity3D游戏开发之网络游戏服务器架构设计培训(如何做一名好主程)

在我们初期学习Unity3D培训目标:让U3D初学者可以更快速的掌握U3D技术,自行制作修改素材,可以独立完成2D.3D小规模游戏及网页游戏开发.后面就应该朝着主程的方面前进 今天给大家讲一下如何做一个好的主程 入手 假如,我现在接手一个新项目,我的身份还是主程序.在下属人员一一到位之前,在和制作人以及主策划充分沟通后,我需要先独自思考以下问题: 1.服务器跑在什么样的操作系统环境下?2.采用哪几种语言开发?主要是什么?3.服务器和客户端以什么样的接口通讯?4.采用哪些第三方的类库? 除了技术背

Unity3D手游-横版ACT游戏完整源码下载

说明: 这不是武林,这不是江湖,没有道不完的恩怨,没有斩不断的情仇,更没有理不清的烦恼,这是剑的世界,一代剑魁闯入未知世界,将会为这个世界展开什么样的蓝图,让你来创造它的未来,剑魁道天下,一剑斗烛龙!!! 游戏开发了三个月,非常值得收藏,至于做什么用途,就看你自己啦!来来来,放大招了!请看附件:) 测试环境: Unity3D 4.3.4 运行效果: 完整源码下载http://www.yxkfw.com/thread-5035-1-1.html

unity3D中协程和线程混合

这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子: 大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了这样的使用方法: IEnumerator LongCoroutine() { yield return StartCoroutine(DownloadZip()); ExtractZip(); yield return StartCoroutine(LoadZipContent()); } 可是Ex

【Unity3D游戏开发】—— 太空大战打飞机游戏详解

大家好我是Kaven,今天给大家带来的是一个Unity3D的打飞机的小项目.俗话说"眼看千变,不如手过一边",学了差不多两星期Unity3D了,是时候找个小项目练练手了.于是就翻出了cocos2d-x的一个例子,模仿着写了一个飞机大战的游戏,虽然有一些功能没有实现,但总体上是完成了.闲话少说,下面开始吧. 由于这个用的是Unity3d自带的原生的2D插件native 2d,所以创建项目时左下角选择2d. 这个小游戏我分了三个场景,菜单场景,游戏场景,结束场景.由于菜单场景与结束场景都比

Unity3D中的线性插值Lerp()函数解析

转自:http://www.aichengxu.com/view/2446604 在unity3D中经常用线性插值函数Lerp()来在两者之间插值,两者之间可以是两个材质之间.两个向量之间.两个浮点数之间.两个颜色之间,其函数原型如下: 1.Material.Lerp 插值 function Lerp(start : Material, end : Material, t : float) : void 在两个材质之间插值 2.Vector2.Lerp 插值 static functionLer

Unity3d开发(十八) 监听编辑器状态改变,制定自定义回调

div#cpcontent2 {height:215px;width:215px;float:left;} div#cpmenu {height:200px;float:left;} div#cpcontent {height:200px;width:150px;float:left;} 文章作者:松阳 原文链接:http://blog.csdn.net/fansongy/article/details/53318791 做编辑器插件时,我总是想要拿到监听编辑器的状态变化.比如在打开编辑器开始运