以前写过一篇自动生成脚本的工具,可是我给它起名叫半自动代码生成器。之因此称之为半自动,由于我以为全自动代码生成器应该作到两点:代码生成+自动绑定。以前的工具只作了代码生成,并无作自动绑定,因此鄙人又花时间研究了CocosCreator的预制体文件,实现了自动绑定的能力,而且支持了插件使用方式。node
本篇内容,不只仅是宣传本身的插件工具,还会帮助你们分析一下Creator的预制体文件格式,使购买插件的同窗能够将插件价值最大化,也能让读者对Creator的预制体文件有所了解。json
[ { "__type__": "cc.Prefab", "_name": "", "_objFlags": 0, "_native": "", "data": { "__id__": 1 }, "optimizationPolicy": 0, "asyncLoadAssets": false, "readonly": false }, { "__type__": "cc.Node", "_name": "LoginView", "_objFlags": 0, "_parent": null, "_children": [ { "__id__": 2 }, { "__id__": 6 }, { "__id__": 18 }, { "__id__": 21 }, { "__id__": 33 }, { "__id__": 42 }, { "__id__": 63 }, { "__id__": 84 } ], "_active": true, "_components": [ { "__id__": 105 }, { "__id__": 106 } ], "_prefab": { "__id__": 107 }, "_opacity": 255, "_color": { "__type__": "cc.Color", "r": 255, "g": 255, "b": 255, "a": 255 }, "_contentSize": { "__type__": "cc.Size", "width": 960, "height": 640 }, "_anchorPoint": { "__type__": "cc.Vec2", "x": 0.5, "y": 0.5 }, "_trs": { "__type__": "TypedArray", "ctor": "Float64Array", "array": [ 480, 320, 0, 0, 0, 0, 1, 1, 1, 1 ] }, "_eulerAngles": { "__type__": "cc.Vec3", "x": 0, "y": 0, "z": 0 }, "_skewX": 0, "_skewY": 0, "_is3DNode": false, "_groupIndex": 0, "groupIndex": 0, "_id": "" } ]
当你第一次看到这个文件的时候可能会有所疑惑,此文件是一个一维数组的json对象。
数组第一个位置是预制体文件的描述能够忽略。第二个位置的对象就是这个文件根节点对应的属性了。也是最重要的部分。从数据的_children 和_components字段能够看出,引擎是根据__id__这个字段来寻找其余数据的。只不过这个__id__并不是你所理解的id,而是数组的索引位置。而且配置中全部涉及到寻找其余数据都是用的这种__id__方式。包括给本身的脚本组件绑定节点。数组
因为咱们是要导出和绑定其中的属性,因此咱们只关注__type__,_name,_childern,_components这几个属性就能够了。async
__type__: 是一个比较重要的属性,对于普通的组件,类型会是cc.Node,cc.Sprite,cc.Button之类的。对于脚本的类型比较特别,它并非你定义的类名,而已一串通过处理的字符。可是它的特色就是长。因此我会用长度是否大于20来判断是不是脚本组件。
下方是我已经作好绑定脚本的配置内容。也说明若是你要给预制体添加脚本也就是给预制体的数组添加一个下面格式的配置而已。经过下方的配置也能够看出我给这个脚本绑定了start$VButton,login$VLabel,login$\VLabel,show$VRichText四个变量和testItem$ATestItemView一个数组。编辑器
{ "__type__": "3e347nRcdVAiYpq6icd+8+w", "_name": "", "_objFlags": 0, "node": { "__id__": 1 }, "_enabled": true, "start$VButton": { "__id__": 14 }, "login$VLabel": { "__id__": 19 }, "back$VButton": { "__id__": 29 }, "show$VRichText": { "__id__": 40 }, //绑定的是一个数组,长度为3 "testItem$ATestItemView": [ { "__id__": 61 }, { "__id__": 82 }, { "__id__": 103 } ], "_id": "" },
固然这里边还有一个问题就是一个节点可能挂了不少组件,那咱们要怎么出理呢?
首先是作一个筛选,只有给定的组件才能够输出
var NORMAL_COMP_LIST = ['cc.Label', 'cc.Sprite', 'cc.RichText', 'cc.Button', 'cc.ScrollView']
其次工具会将名称后边加上类型,以区别不一样的组件的状况。
所以这也是一个可自定义和扩展的部分。工具
_children: 就是遍历的节点,咱们不用关心这个配置文件的数组有多长,就从这些子节点深度遍历就能够了。ui
_components: 遍历每一个节点的时候咱们再遍历一次它的全部组件,而后作上边咱们说的操做。这样一个文件走一遍以后咱们的类须要的信息也就生成了。插件
既然脚本的类型是 "type": "3e347nRcdVAiYpq6icd+8+w",那么咱们怎么找到对应的脚本文件的名称呢?
当你右键一个脚本文件,点击打开Library中的资源选项,会跳转到一个js文件中
这个文件有四个特色,一是它的文件名是你脚本的uuid.js。二是文件带有cc._RF.push(module,,三是带有类型"3e347nRcdVAiYpq6icd+8+w"。四是带有脚本名称。因此你只要查找文件中带有cc._RF.push(module,字段而且带有你传入的类型的文件并返回后处理一下就能够得到脚本名称了。固然也能够获得路径并作好import from 的设置。
这里可能有人会以为,搜索整个imports路径是否是很慢,其实不是,即便再慢还能比手动绑定慢吗?因此这个速度能够无视。3d
怎么处理的creator自带的meta机制,我是将代码生成和自动绑定分红两个脚本。代码生成以后会刷新生成脚本的目录,而后再调用自动绑定的脚本。刷新预制体目录。
这里边一直强调的就是刷新指定的目录,而不是刷新整个assets或者整个Script。缘由是我在使用的时候发现,刷新整个目录会形成编辑器卡死,体验很很差,因此当你不设置的脚本目录不存在就作导出时,creator显示的目录位置不是实际中硬盘中显示的位置,重启编辑器后才会正确,就是由于我刷新的目录是你指定的目录。若是指定的目录不存在,目录会建立,可是不会刷新。
刷新后的预制体文件可能会报错,能够无视,双击预制体文件从新查看就能够了。code
如何作到绑定嵌套的预制体的节点?
首先在导出代码的时候一旦遇到有脚本的节点就返回。继续遍历其余子节点。这样你的脚本里就不会声明其余脚本要声明的内容。
而后在绑定的时候首先会找到应该作数据绑定的脚本,而后再深刻遍历,当你发现你处理的这个节点上有脚本的时候就会用它身上脚本处理它的子节点。因此若是一个节点有多个脚本就只能绑定第一个脚本的数据。
根据预制体文件生成脚本
自定义输入目录和输出目录
自动绑定属性+数组
使用$V标识变量
使用$A标识数组
属性名称默认带有类型。
自动绑定button事件
可扩展导出属性类型
自动绑定其余预制体的属性,和button事件
自动导入使用到的其余脚本
手懒不想本身实现的能够关注公众号,进入微店购买。
欢迎扫码关注公众号《微笑游戏》,浏览更多内容。