unity lightast light 第15关怎么过

Metro: Last Light
Welcome to nosTEAM.ro. Please
Hello and welcome to ^^nosTEAM^^ Games ForumLIKE and SHARE our facebook page程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
CSLight研究院之学习笔记结合NGUI(一)
CSLight研究院之学习笔记结合NGUI(一)
围观11639次
编辑日期: 字体:
这两天一直在研究CSLight,目前Unity热更新的方式有两种,一种是ulua这个网上的例子已经很多了。还有一种就是CSLight。其实我更希望CSLight可以趋向成熟,因为它的语法就是C#,但是有些C#的标准语法用不了。这两天我学习的做了一个例子,也把我遇到的坑记录一下。
1.在github上下载CSLight,当我把DLL拖进项目的时候会报错。原因是CSLight的dll和NGUI的冲突了,所以我直接把他的core文件夹代码全部拷贝在我的工程里面。
2.脚本可以直接就创建成.cs文件,这样可以利用unity的语法提示。李总真是太聪明了哈哈。
3.脚本与类之间传递参数。。如下脚本所示,调用脚本UIMain中的Start()方法,并且将名子作为参数传递了进去。
12345678910111213
using UnityEngine;using System.Collections;using System.Collections.Generic;using System;&public class UICommon : MonoBehaviour {& void Start () {
ScriptMgr.Instance.LoadProject();
ScriptMgr.Instance.Execute("UIMain.Start(\""+name+"\");"); }}
ScriptMagr是李总封装的脚本管理类,是一个静态类。因为我们在脚本中可能会用到一些数据对象,需要提前注册一下,每次打开界面都去注册一下显然不太好。LoadProject()等于就是开游戏的时候注册一下,以后直接就去用。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
using UnityEngine;using System.Collections;using System.Collections.Generic;using System;&&/// &summary&/// 这个类实现脚本的Logger接口,脚本编译时的信息会从Log输出出来/// &/summary&class ScriptLogger : CSLE.ICLS_Logger{&&&&&public void Log(string str)&&&&{&&&&&&&&UnityEngine.Debug.Log(str);&&&&}&&&&&public void Log_Error(string str)&&&&{&&&&&&&&Debug.LogError(str);&&&&}&&&&&public void Log_Warn(string str)&&&&{&&&&&&&&Debug.LogWarning(str);&&&&}}&public class ScriptMgr{&&&&/// &summary&&&&&/// ScriptMgr用单例模式,主要是为了提供C#Light Env的初始化&&&&/// &/summary&&&&&public static ScriptMgr Instance&&&&{&&&&&&&&get&&&&&&&&{&&&&&&&&&&&&if (g_this == null)&&&&&&&&&&&&&&&&g_this = new ScriptMgr();&&&&&&&&&&&&return g_this;&&&&&&&&&}&&&&}&&&&#region forInstance&&&&static ScriptMgr g_this;&&&&public CSLE.CLS_Environment env&&&&{&&&&&&&&get;&&&&&&&&private set;&&&&}&&&&private ScriptMgr()&&&&{&&&&&&&&env = new CSLE.CLS_Environment(new ScriptLogger());&&&&&&&&env.logger.Log("C#LightEvil Inited.Ver=" + env.version);&&&&&&&&&RegTypes();&&&&}&&&&#endregion&&&&&&/// &summary&&&&&/// 这里注册脚本有权访问的类型,大部分类型用RegHelper_Type提供即可&&&&/// &/summary&&&&&void RegTypes()&&&&{&&&&&&&&//大部分类型用RegHelper_Type提供即可&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Vector2)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Vector3)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Vector4)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Time)));&&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Debug)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(GameObject)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Component)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(UnityEngine.Object)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Transform)));
env.RegType(new CSLE.RegHelper_Type(typeof(Resources)));&&&&&&&&&//对于AOT环境,比如IOS,get set不能用RegHelper直接提供,就用AOTExt里面提供的对应类替换&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(int[]), "int[]"));//数组要独立注册&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(List&int&), "List&int&"));//模板类要独立注册&&&&&&&&&&&//每一种回调类型要独立注册&&&&&&&&env.RegDeleType(new CSLE.RegHelper_DeleAction("Action")); //unity 用的dotnet 2.0 没有Action&&&&&&&&env.RegDeleType(new CSLE.RegHelper_DeleAction&int&("Action&int&")); ;
env.RegDeleType(new CSLE.RegHelper_DeleAction&GameObject&("Action&GameObject&")); ; &&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(Rect)));&&&&&&&&env.RegType(new CSLE.RegHelper_Type(typeof(PrimitiveType)));
env.RegType(new CSLE.RegHelper_Type(typeof(UICommonEvent)));&&
env.RegType(new CSLE.RegHelper_Type(typeof(UISprite)));&&&&}&&&&&public bool projectLoaded&&&&{&&&&&&&&get;&&&&&&&&private set;&&&&}&&&&public void LoadProject()&&&&{&&&&&&&&if (projectLoaded) return;&&&&&&&&try&&&&&&&&{&&&&&&&&&&&&string[] files = System.IO.Directory.GetFiles(Application.streamingAssetsPath, "*.cs", System.IO.SearchOption.AllDirectories);&&&&&&&&&&&&Dictionary&string, IList&CSLE.Token&& project = new Dictionary&string, IList&CSLE.Token&&();&&&&&&&&&&&&foreach (var v in files)&&&&&&&&&&&&{&&&&&&&&&&&&&&&&var tokens = env.tokenParser.Parse(System.IO.File.ReadAllText(v));&&&&&&&&&&&&&&&&project.Add(v, tokens);&&&&&&&&&&&&}&&&&&&&&&&&&env.Project_Compiler(project, true);&&&&&&&&&&&&projectLoaded = true;&&&&&&&&}&&&&&&&&catch (Exception err)&&&&&&&&{&&&&&&&&&&&&&Debug.LogError("编译脚本项目失败,请检查" + err.ToString());&&&&&&&&}&&&&}&&&&public void Execute(string code)&&&&{&&&&&&&&var content = env.CreateContent();&&&&&&&&&&try&&&&&&&&{&&&&&&&&&&&&var tokens = env.ParserToken(code);&&&&&&&&&&&&var expr = env.Expr_CompilerToken(tokens);&&&&&&&&&&&&expr.ComputeValue(content);&&&&&&&&}&&&&&&&&catch (Exception err)&&&&&&&&{&&&&&&&&&&&&var dumpv = content.DumpValue();&&&&&&&&&&&&var dumps = content.DumpStack(null);&&&&&&&&&&&&var dumpSys = err.ToString();&&&&&&&&&&&&Debug.LogError(dumpv + dumps + dumpSys);&&&&&&&&}&&&&}}
大家注意看RegTypes()里面的注册方法。把你的脚本中用到的类,可以是unity提供的类,可以是NGUI提供的类,也可以是你自己封装的类都在这里注册一下,只有注册了你的脚本里才能使用这些方法。
假如界面Prefab在Assetbundle里面热更新了,那么脚本也对应需要更新,比如之前的界面只有一个按钮,那么新更新一个界面有两个按钮了,那么需要给新增加的按钮加监听事件。先看看下面可以热更新的这条脚本。
123456789101112131415161718192021222324252627282930313233343536373839
using UnityEngine;using System.Collections;&public class UIMain&&{& static GameObject button ; //UICommon里面调用脚本的Start方法,并且传入了名子的字符串 static void Start (string root)
Transform rootUI = GameObject.Find(root).transform;
//在Resources下面读取资源或者 Assetbundle来读取,并且实例化在场景视图中。这一句操作我觉得也可以在Unity的脚本中完成
GameObject prefab&&= Resources.Load("UIMain") as GameObject;
GameObject gameObject = Object.Instantiate(prefab) as GameObject;
//放在UIPanel下面,让坐标在原点
gameObject.transform.parent = rootUI;
gameObject.transform.localPosition = Vector3.zero;
gameObject.transform.localScale = Vector3.one;&
Transform transform = gameObject.transform;
//找到UIPrefab下面的一个Sprite并且修改一下Sprite的名子。
UISprite sprite = transform.Find("Sprite").GetComponent("UISprite")as UISprite;
sprite.spriteName ="Glow";
sprite.transform.localPosition = new Vector3 (10,100,0);
sprite.MakePixelPerfect();&
//获取按钮对象,并且增加按钮的监听
button = transform.Find("Button").gameObject;
UICommonEvent.onClick +=Click;
UICommonEvent.AddOnClick(button); }
//当按钮点击的时候在脚本中得到回调 static void Click(GameObject go) {
if(go.name == button.name){
Debug.Log("雨松MOMO提示,您点击了这个按钮喔");
代码写完你会发现几乎和C#的脚本万全一样,但是有几个比较恶心的地方。
1.不支持范型。
热更新的这样的代码就不能直接使用了。
Resources.Load&GameObject&
gameObject.GetComponent&UISprite&
2.不支持typeof()关键字
3.不支持代理事件。
用NGUI做界面,可能里面用了大量的UIEventListener ,比如按钮、精灵的位移动画等等。这种东西如果硬要在脚本里面写太蛋疼了。我觉得最好还是把代理相关的东西拿出来。
还有就是做界面的时候可能会用到一些定时器,如果用代理来做的话也需要改改,总之向这种delegate回调的地方应该都要封装成方法,然后在回调进脚本里面。
在上面的代码中,我在处理按钮的点击事件的时候。如下代码所示,我写了一条Unity的脚本,在热更新的脚本里面,通过类名.就可以直接访问方法并且传递参数。UIEventListener监听到事件以后,在回调一下热更新脚本中的方法。
class UICommonEvent{ public static event Action&GameObject& onClick; static public void AddOnClick(GameObject button) {
UIEventListener.Get(button).onClick =delegate(GameObject go) {
onClick(go);
注:我也不是CSLight的高手,也是最近开始学。感谢作者给我了很大帮助,他的游戏项目中大量的使用CSLight。据说效率还可以,这两天我在好好测试一下它的效率,希望有经验的朋友可以分享一些。谢谢啦。
最后本文下载:
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!

我要回帖

更多关于 unity light 的文章

 

随机推荐