接着上一篇的内容
继续来挑战下一个难点:
自我入侵。
使用
Creaotr v3.x
开发的项目,作为Creator v3.x
自己的插件,运行,并且和宿主进行交互
从某种意义上来说过,这个挑战要比上一个难度高上许多。
因为 Creator v3.x
的材质系统,一些基础概念,和 Creator v2.x
还是有很多相似的地方的。
但在框架设计上 Creator v3.x
和 Creator v2.x
有很多不一样的地方,尤其是这次要挑战的和 启动
相关的部分,更是如此。
话不多说,开始搞起来,还是要先说明下:
这只是一篇记录如何一步一步
推理 – 尝试 – 报错 – 排错 – 推理 – 尝试 – 报错 – 排错 – …
不停的循环,直到最后实现目标的流水账,没有什么太大的亮点,除了图片贼多 ~~~
Step.0
首先明确挑战的目标,需求是怎样的:
把上一次用
Creator v3.x
做的动态材质生成的项目,进行发布将发布后的产物,包装为
Creator v3.x
标准格式的插件确保插件可以被
Creator v3.x
的项目识别,加载并运行
Step.1
把上一次用
Creator v3.x
做的动态材质生成的项目,进行发布
这个没什么技术含量,直接发布项目为 Web-Desktop
即可
为了后续调试方便,这里发布选择了调试模式。
顺便测试下,发布的项目本身,是可以在浏览器中正常运行的。
Step.2
后续在实现功能排错的过程中,需要反复的把插件中的报错和这个网页版进行对比,或是同步调试,查看流程。
所以这里用 MAMP
单独给这个发布后的 Web-Desktop
开一个本地 Web服务器
, 方便随时运行,断点调试。
Step.3
接着是:
将发布后的产物,包装为
Creator v3.x
标准格式的插件
首先是根据文档,凹一个空的插件项目出来:
这里有详细的说明,照着做,不会有什么问题
我这里为了方便,直接就借用以前做过的 ssr-shaderfx-gallery
来快速开始:
然后就能在 扩展管理器
里面,刷到本地的插件项目了。
启用后,菜单栏里面,项目也就出现了。
Step.4
接着,来明确一下希望的实现的插件的项目架构是怎样的:
Editor / 编辑器
中有各种插件,引擎的,用户的。
这里的 MyPlugin
就是我们自己的插件。
正常情况下,在自己的插件中,可以使用各种 html + css + javascript
来进行插件的开发,也可以用一些框架 vue / react ......
应该是怎么都行。
( 但是由于自己对这些技术都不熟悉,想要用 html + css + javascript
撸个简单的界面都要我老命,所以才有了这次挑战的出现。)
**借用
Creator v3.x
快速方便的进行可视化的界面功能,软件的调试编写,就像做游戏一样 **将产物直接作为
Creator v3.x
自己的插件使用这样在很大程度上降低了插件开发的学习成本,同时也在一定程度上提高了开发的效率
参照上图,这里的 Web App
其实对应的,就是前面发布出来的 Web-Desktop
项目。
这次挑战的主要点,就是让这个内置在插件中的 Web-Desktop
项目,可以被正确的加载和运行。
Step.5
明确了这个插件解决方案的结构,那就继续开干,先把 Web-Desktop
拷贝到插件项目里。
直接运行肯定是不会有任何效果的,也不会也任何报错,因为并没有人去理会这个 Web-Desktop
项目。
在网页中它能跑起来,是因为有 index.html
这个入口文件,把它给启动起来。
先来看看 index.html
这个的内容:
可以看到,和以前的 cocos2d-js / creator v2.x
的启动部分已经有了相当大的差异了,但是核心还是没变:
- 有个
canvas
用来渲染游戏- 一些先导入的启动脚本
js
- 一句用于启动的代码
System.import
有了这几个点,游戏就被启动起来,并且渲染到网页中了。
Step.6
于是就照着上面的流程,来尝试修改下,在 Creator v3.x
插件系统中,相当于 index.html
地位的文件 index.js
:
可以看到,3个部分正好和前面分析的 index.html
一一对上:
一堆
js
的import
一个最重要的
Canvas
一句用来启动的代码
index.html
有一句:
<script src="src/import-map.json" type="systemjs-importmap" charset="utf-8"> </script>
暂时不知道是什么鬼,就先不管它。
然后当然是运行看看:
界面什么都看不到加上一些报错,当然这也是很正常的事情,要是这么简单就能出来,那才见鬼了。
Step.7
只要有报错,那就一切好办,简单分析一下就行了。
首先这个是非常常见的一种错误,是由相对绝对路径/绝对路径
造成的。
这里可以看到插件启动的时候 index.js
文件找到了 Cocos Creaator 编辑器
源码里去了。
知道问题那就好说,换换指定的文件路径试试:
再次运行:
不错,开始报别的错了,那就继续。
Step.8
看这报错,应该是开始启动加载资源报错了,那就没办法,是时候把之前准备好的网页版拿出来,跟着 System.import
大致的 Step
一下,看看有哪些流程了。
此处省略 ??? 字扒源码的流程 …
在看流程的同时,自然也就发现了前面报错相关的地方:
大致地方也找到了,那就用 同步调试 的方式,来进一步定位下可能是哪里的问题。
简单来说,就是 网页版
和 插件版
同时运行,单步调试,对比两边的有一些数据变量,这里必然会有差异的地方,那基本就是出错的地方了。
一顿操作后,发现了可疑的地方:
插件版本中,到这里后,imports
是空的。
但是网页版,确有着明确的值。
这里看着 importMap
有点眼熟,突然想到了前面因为搞不懂用处,没有去管的代码:
<script src="src/import-map.json" type="systemjs-importmap" charset="utf-8"> </script>
看来和这个是有点关系了。
Step.9
继续推理,import-map.json
这文件是有的:
{
"imports": {
"cc": "./../cocos-js/cc.js",
"wait-for-ammo-instantiation": "./../cocos-js/wait-for-ammo-instantiation.js"
}
}
内容看着就很像上面报错相关的东西,显然这个东西不能不管。
实际的网页版中,用的是下面的代码:
<script src="src/import-map.json" type="systemjs-importmap" charset="utf-8"> </script>
这里因为实在不知道对应成代码应该是什么样的,于是尝试了:
require("../ssr-shaderfx-gallery/src/import-map.js");
但是,同样还是报错。
显然不能乱写。
type="systemjs-importmap"
这个部分还是很特别的,于是试着源码里找一找:
找到了地方,果然是有特殊的操作的。
于是继续跟一跟,主要想看下,这个到底是要 import
个啥。
最后发现,做的事情,其实差不多就是把 import-map.json
里配置好的代码,加载到这个 imports
的部分。
知道了怎么用,用来干嘛,那就直接尝试暴力赋值试一试,你(引擎)要什么,我就让你获取到什么 :
执行一看,果然不报错了:
但是再细看,发现遇到了更麻烦的问题,卡死 了
整个插件卡死了,界面卡死,
DevTools
卡死,所以没有继续的输出了原来不是搞定了 ~~~
Step.10
说实话,这个是比较麻烦的情况,你要有个报错,还可以看看堆栈,搞搞,啥都没有,这就不妙了。
不过推理还是可以继续的
出错的大致部分,可以肯定是在资源加载这段,既然是卡死了,那么八成就是死循环了。
既然如此,直接在引擎的几个启动文件中,搜索类似
do while
的部分即可。
听着很合理,那就开始查,往死里查 ~~~
此处省略 ??? 字断点调试的的流程 …
终于,找到了 凶手:
这段代码主要是 解析文件路径用的,具体功能不去深究, 正常情况下,这些输入的待解析路径是长这样的:
http://localhost:8888/3d/cocos-js/wait-for-ammo-instantiation.js
于是不停循环找前一个 /
,知道最后都没找到合适的话,就返回。
但是插件中,这里的路径是我写死的:
/Users/....../cocos-js/wait-for-ammo-instantiation.js
没想到的是,上面的 do while
在这 /
开头的字符串的情况下,就会死循环了…
知道了原因,那就改一下:
file:///Users/....../cocos-js/wait-for-ammo-instantiation.js
可以看到,死循环过了,插件没有被卡死,接着输出了下面的报错,很熟悉的报错不是什么大问题。
Step.11
经历了上面这些过程,这样的报错实在是太简单了,直接快速的定位解决:
这样一来,数据就读到了,那就跑起来继续走。
看到这里,因为有了过去 Creator v2.x
同样的解决方案研究的经历,其实就知道,启动加载的部分基本已经过去,至于是否正确,那得等到看到成功启动的插件内的界面才知道。
Step.12
继续定位上面的报错,非常简单:
为什么找不到呢,那肯定是因为发布的网页版项目和现在处于插件环境的项目,在 DOM
结构上是有区别的:
插件系统中,想要的 Canvas
在这里。
那么就简单了,改改代码:
Canvas
就到手了。
继续走,惊讶的发现,竟然已经可以看到 Splash
的部分了:
报错的内容,也还是熟悉的味道。
Step.13
再次定位错误:
这个好说,简单改一下:
继续走:
终于,看到想要看到的东西了。
Step.14
到这里其实基本就挑战成功了。顺便继续试试这个方案有没有之前 Creator v2.x
遇到的不足的地方。
首先是 float
状态缩放,界面是否能完美的实时适配:
不错,适配自动就是完美的。
接着试试,float
切换 dock
是否会有报错问题:
没有问题,float
切换 dock
再切回来,全部都没有任何报错。
一点小问题是 dock
状态下,界面适配有点小瑕疵,不过这点小问题,后续肯定可以解决的,暂且忽略。
到这里,这次的挑战基本就结束了。
虽然期间有很多 Hard Code
的部分,不过这些知识为了快速进行可行性尝试而写的,后续在整理成框架和解决方案的时候,替换成变量就可以了。
因为有了之前 Creator v2.x
的转换插件的经验,这次的挑战少走了不少的弯路,否则估计也很难搞个半天就能够成功的实现想要的效果。
难点还有一个,蓝图框架的 Creator v3.x
化。
不过这个活其实就是一个 js
转 ts
的事情,加上把一些用到的 v2/v3
有差别的组件进行翻译的过程。
难度应该不高,可惜自己 ts
完全不会,这个翻译估计又要趟不少坑,不知道是不是有什么工具,可以自动把之前全套 js
代码的结构,转换成 ts
风格的,内部调整当然我可以自己慢慢来。
不管怎样,下个挑战,继续 ~~~