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中……如果推进下去。

 

返回:JSBinding+Bridge.NET:Unity游戏热更新方案

posted on 2017-01-04 09:14  AnswerWinner  阅读(908)  评论(0编辑  收藏  举报

导航