JSBinding+Bridge.Net:框架代码与逻辑代码的关系
在JSB+Bridge工程中你可以同时维护Cs版本和Js版本的游戏。
框架代码:简称framework,表示那些不进行热更的代码。注意,这包括你自己写的代码,也包括引用的Dll,比如UnityEngine.dll,或者是其他第3方Dll,都算是框架代码。
逻辑代码:简称logic,表示那些可进行热更的代码。逻辑代码将会变成Js代码。
1. 在Cs工程中,将代码明确划分为框架和逻辑。框架代码放在 Assets/Scripts/GameFramework(有源代码,或者Dll也放这个目录下吧),逻辑代码放在 Assets/Scripts/GameLogic。游戏运行过程中,框架代码跑的是C#,逻辑代码跑的也是C#。
2. 在Js工程中,框架代码也是在 Assets/Scripts/GameFramework 下,这个目录是从Cs工程映射过来的,修改任意一边的内容,另外一边就会自动变化。逻辑代码则是放在 Assets/StreamingAssets/JavaScript/Gen2.javascript 中的。Gen2是Cs工程下的逻辑代码编译生成的Js代码。在游戏运行过程中,框架代码跑的是C#,逻辑代码跑的是Js。
3. 在BridgeProj工程中,把 Cs工程下 Assets/Scripts/GameLogic 整个目录映射过来。他的目标是把这些逻辑代码编译生成Js代码给Js工程使用。这里会有个问题,逻辑代码是可以依赖框架代码的,如果只是把逻辑代码映射到BridgeProj工程中,是不可能编译得过的。这个问题是通过csw.cs解决的。
csw.cs详解
假设逻辑代码里使用了 Debug.Log() 函数,鼠标定位在Log函数上,按F12进行跳转
在Cs工程中,Log函数会跳转到
很显然,这个Log函数就来自于UnityEngine.dll。
如果是BridgeProj工程中,对Log函数跳转,则会跳转到csw.cs中:
为什么是这样的呢?
1. 首先,在csw.cs中的类都会被打上这个标签:
[Bridge.FileName("csw")]
表示这个类生成Js代码后,文件名叫csw.js。
2. 另外,BridgeProj工程下的 bridge.json 里有这么一句:
"outputBy": "Project",
表示,所有逻辑代码都会被生成到{工程名}.js文件中,我们的工程叫 BridgeProj,所以所有逻辑代码都会生成到BridgeProj.js中。
顺便说一下,为什么我们要生成到同一个文件中去。在Bridge中,Js加载时,都是通过Bridge.define这个函数来定义一个类的(打开 BridgeProj.js 就会看见了)。Bridge.define有个要求是,父类必须在前面定义,否则加载Js时报错,说父类找不到。生成到同一个文件中去的话,是由Bridge来保证这个定义顺序。如果生成到多个文件中去,我们自己在加载的时候,无法确定加载顺序是什么。
注意:Bridge.FileName 标签优先级较高,所以csw.cs还是生成到csw.js中。可参考Bridge文档:http://bridge.net/docs/global-configuration/
3. 在BridgeProj成功编译后,我们会返回Js工程中点击菜单:JSB | Update JavaScript。这个菜单做啥事呢?其实很简单,就是把BridgeProj生成的 BridgeProj.js 拷贝到 Js工程下的 Assets/StreamingAssets/JavaScript/Gen2.javascript。
这里注意,csw.js 被抛弃了。
4. 打开 Gen2.javascript,查找 Debug.Log 对应的那一行Js代码,是长这样的:
UnityEngine.Debug.Log("123");
那么在Js中,UnityEngine.Debug.Log在哪里定义的呢?答:是在 Gen1.javascript 中定义的,可以在 Gen1 中搜索 "UnityEngine.Debug"(包括引号)中可查到 Debug 类的定义。
5. Gen1 是什么时候生成的?答:是在点击菜单 JSB | Gen Bindings 时(此步骤称为“导出”)生成的。也就是说,跟 csw.cs 是同时生成的。Gen1这个Js文件很重要,他负责对接逻辑代码(即Js代码)与框架代码(即C#代码)。在Js中,任何需要调用到C#功能的,都会经过Gen1。
6. 结论:csw.cs 在BridgeProj中的作用之一是让他可以编译通过。
csw.cs实际上就是导出的那些类(*)。他生成 csw.js。
而导出的类,生成的Js代码是 Gen1。
因此,csw.js 与 Gen1 是一一对应的,只不过只有在Gen1 中函数才有实现。所以我们不会把 csw.js 拷贝到 Js 工程中。
(*):注意:实际上,csw.cs比导出的那些类还要“多一点东西”。 举个例子,框架代码里有类A和类B,假设类A长这样:
class A
{
public void Hi(B b){}
}
我可以选择只导出类A,可以吗?可以的。但是,有个问题,如果B不出现在 csw.cs 中,那么,csw编译不过,因为找不到B。
所以,csw.cs比导出的那些类,多出来的东西就是。。。为了能够编译通过所需要的任何东西。在上面的例子中,我们发现A的Hi函数里有个参数是B类型的,那么B的定义也得出现在csw.cs中;如果B的函数里又出现了C,那么C也得出现在 csw.cs中……如果推进下去。
posted on 2017-01-04 09:14 AnswerWinner 阅读(916) 评论(0) 编辑 收藏 举报