CSLight学习笔记结合NGUI



这两天一直在研究CSLight,目前Unity热更新的方式有两种,一种是ulua这个网上的例子已经很多了。还有一种就是CSLight。其实我更希望CSLight可以趋向成熟,因为它的语法就是C#,但是有些C#的标准语法用不了。这两天我学习的做了一个例子,也把我遇到的坑记录一下。结合上章NGUI研究之李剑英的CSLight入门指南结合NGUI热更需要的朋友可以看下。

1.在github上下载CSLight,当我把DLL拖进项目的时候会报错。原因是CSLight的dll和NGUI的冲突了,所以我直接把他的core文件夹代码全部拷贝在我的工程里面。

2.脚本可以直接就创建成.cs文件,这样可以利用unity的语法提示。李总真是太聪明了哈哈。

3.脚本与类之间传递参数。。如下脚本所示,调用脚本UIMain中的Start()方法,并且将名子作为参数传递了进去。

1

2

3

4

5

6

7

8

9

10

11

12

13

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()等于就是开游戏的时候注册一下,以后直接就去用。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

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里面热更新了,那么脚本也对应需要更新,比如之前的界面只有一个按钮,那么新更新一个界面有两个按钮了,那么需要给新增加的按钮加监听事件。先看看下面可以热更新的这条脚本。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

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监听到事件以后,在回调一下热更新脚本中的方法。

1

2

3

4

5

6

7

8

9

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。据说效率还可以,这两天我在好好测试一下它的效率,希望有经验的朋友可以分享一些。谢谢啦

CSLight学习笔记结合NGUI

时间: 2024-10-09 20:39:03

CSLight学习笔记结合NGUI的相关文章

NGUI 学习笔记实战——制作商城

Unity3D的uGUI听说最近4.6即将推出,但是目前NGUI等UI插件大行其道并且已经非常成熟,所以我们还是先看眼前吧. 一.实现思想 商城的功能是很多游戏都拥有的,按下一个界面按钮,弹出一个窗体. 然后是商城中的商品可以拖动,既可以用手,也可以用滑条等等,至于点击购买就不单单是UI层的事了.等到实现NDate的时候再进行讨论. 二.实现背景 1.NGUI->Open->Prefab tool bar ,拖一个black widget进去 2.之后布局如下,这些应该没什么难度,弄好锚点,d

NGUI学习笔记(一)UILabel介绍

来个前言: 作为一个U3D程序员,自然要写一写U3D相关的内容了.想来想去还是从UI开始搞起,可能这也是最直观同时也最重要的部分之一了.U3D自带的UI系统,也许略坑,也没有太多介绍的价值,那么从今天开始就记录一下主流的UI插件-NGUI吧. NGUI版本: v3.6.8 学习笔记一 假定大家都已经将ngui导入到了项目中,这里需要注意,插件(.package)的存放路径不能有中文,否则会导致解压失败. 导入之后可以看到几个文件夹咯,Editor,Examples,Resources,Scrip

NGUI学习笔记-UISprite

所有的Sprite使用前,得先准备个图集,然后选择里面的图片进行填充 UISprite里面有几个属性做个笔记: Type: Smple:除了显示内容从图集里面获取外,其他都和Texture一样的绘制 Sliced:这个模式支持九宫格拉伸,让四个角落的图片不变型,点击Sprite右侧的Edit按钮可以进行Sprite数据的编辑,设置Border的值即可. Tiled:瓦片填充,会平铺进行填充 Filled:这个主要用来做技能CD.进度条等用.FillDir设置填充的模式(360度扇形,水平,垂直等

NGUI学习笔记汇总

欢迎来到unity学习.unity培训.unity企业培训教育专区,这里有很多U3D资源.U3D培训视频.U3D教程.U3D常见问题.U3D项目源码,[狗刨学习网]unity极致学院,致力于打造业内unity3d培训.学习第一品牌. NGUI学习笔记 一.NGUI的直接用法 1. Attach a Collider:表示为NGUI的某些物体添加碰撞器,如果界面是用NGUI做的,只能这样添加.(注:用Component添加无效). 2. Attach an Anchor:表示为该物体添加了UIAn

unity3d学习笔记(十九)--ngui制作3d人物头顶的头像和血条

原地址:http://blog.csdn.net/lzhq1982/article/details/18793479 本系列文章由Aimar_Johnny编写,欢迎转载,转载请标明出处,谢谢. http://blog.csdn.net/lzhq1982/article/details/18793479 先上张图,自己做的一个demo. 这里的人物头像和血条是在3d世界生成的,所以有真正的纵深感和遮挡关系,废话不多说,看我是怎么实现的. 第一步,先在UI Root里制作头像和血条. 这个制作步骤基

NGUI学习笔记-Label

属性说明 Overflow: ShrinkContent : 如果文本超出文本框宽度,会自动缩小文本size,使其显示完整 ClampContent : 文本大小固定,超出文本框的部分不会显示,也不会自动换行 ResizeFreely   :  文本框宽高自适应文本的宽高 Spacing: x:文本字符水平间隔 y:文本字符垂直间隔 MaxLines: 值为0时,行数不限:值大于0,为最大行数 NGUI学习笔记-Label

NGUI学习笔记(五):缓动

在Unity3D中可以使用自带的Animation制作任意形式的动画,不过我们这篇笔记主要是学习和使用NGUI提供的Tween动画.NGUI提供的Tween库功能较为简单,主要是用来实现NGUI自身需要的一些缓动效果,同时我们也可以使用NGUI的Tween来实现一些简单的动画效果. Tween组件 我们选中添加到舞台的任意UI组件右键就能看到添加Tween的菜单,如图: 我们通过选择添加对应的缓动组件就可以添加对应的缓动效果了,下面先简单的看一下NGUI提供的缓动组件的功能: Alpha:透明度

NGUI 学习笔记之一 ScrollView

一.createScrollView 1.First, select the panel you want to be your scroll view and right-click anywhere in the Scene View to bring up the context menu, then choose Attach -> Scroll View. 2.The last step is to add the UIDragScrollView script to at least

Unity3D之UGUI学习笔记(一):UGUI介绍以及Canvas

UGUI是Unity3D4.6官方提供的UI系统,支持2D和3D UI的开发. Unity3D UI史 OnGUI 在Unity4.6之前,官方提供的是OnGUI函数来开发UI界面,当然问题也比较多,首先不支持可视化开发,其次UI始终位于所有3D对象的上方,无法实现在UI上添加3D模型的效果. 现在一般这套系统多用来在Unity编辑器中开发界面或者快速搭建一些调试界面时使用. NGUI 大名鼎鼎的NGUI是可以看做是开发Unity游戏必备的插件,支持可视化开发,同时也支持2D和3D UI的开发,