前言
- 之前写过一篇主动生成脚本的工具,然而我给它起名叫半自动代码生成器。之所以称之为半自动,因为我感觉全自动代码生成器应该做到两点:代码生成+主动绑定。之前的工具只做了代码生成,并没有做主动绑定,所以鄙人又花工夫钻研了CocosCreator的预制体文件,实现了主动绑定的能力,并且反对了插件应用形式。
- 本篇内容,不仅仅是宣传本人的插件工具,还会帮忙大家剖析一下Creator的预制体文件格式,使购买插件的同学能够将插件价值最大化,也能让读者对Creator的预制体文件有所理解。
Creator 预制体文件格式剖析
- 首先咱们展现一小段预制体文件。
[ { "__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这几个属性就能够了。
- __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": "" },
- _name: 它是所有节点的名称,留神,组件是没有名称的,所以咱们解决文件的时候也是从根节点深度遍历所有的子节点,而后在遍历节点的时候出理它的组件。
因为Creator的节点都是有名称的,而且还有空格,反对重名,这些都是代码生成器所不容许的。所以如果你想导出一个属性就要用特定的字符标识。
比方工具当初应用的是$V标识输入的是一个变量。$A标识输入的是一个数组,当然数组还须要名称都雷同。
var TAG = '$V'
var LIST = '$A'
当然这里边还有一个问题就是一个节点可能挂了很多组件,那咱们要怎么出理呢?
首先是做一个筛选,只有给定的组件才能够输入
var NORMAL_COMP_LIST = ['cc.Label', 'cc.Sprite', 'cc.RichText', 'cc.Button', 'cc.ScrollView']
其次工具会将名称后边加上类型,以区别不同的组件的状况。
因而这也是一个可自定义和扩大的局部。
- _children: 就是遍历的节点,咱们不必关怀这个配置文件的数组有多长,就从这些子节点深度遍历就能够了。
- _components: 遍历每个节点的时候咱们再遍历一次它的所有组件,而后做上边咱们说的操作。这样一个文件走一遍之后咱们的类须要的信息也就生成了。
问题探讨
- 既然脚本的类型是 "__type__": "3e347nRcdVAiYpq6icd+8+w",那么咱们怎么找到对应的脚本文件的名称呢?
当你右键一个脚本文件,点击关上Library中的资源选项,会跳转到一个js文件中
这个文件有四个特点,一是它的文件名是你脚本的uuid.js。二是文件带有cc._RF.push(module,,三是带有类型"3e347nRcdVAiYpq6icd+8+w"。四是带有脚本名称。所以你只有查找文件中带有cc._RF.push(module,字段并且带有你传入的类型的文件并返回后处理一下就能够取得脚本名称了。当然也能够失去门路并做好import from 的设置。
这里可能有人会感觉,搜寻整个imports门路是不是很慢,其实不是,即便再慢还能比手动绑定慢吗?所以这个速度能够忽视。
- 怎么解决的creator自带的meta机制,我是将代码生成和主动绑定分成两个脚本。代码生成之后会刷新生成脚本的目录,而后再调用主动绑定的脚本。刷新预制体目录。
这里边始终强调的就是刷新指定的目录,而不是刷新整个assets或者整个Script。起因是我在应用的时候发现,刷新整个目录会造成编辑器卡死,体验很不好,所以当你不设置的脚本目录不存在就做导出时,creator显示的目录地位不是理论中硬盘中显示的地位,重启编辑器后才会正确,就是因为我刷新的目录是你指定的目录。如果指定的目录不存在,目录会创立,然而不会刷新。
刷新后的预制体文件可能会报错,能够忽视,双击预制体文件从新查看就能够了。
- 如何做到绑定嵌套的预制体的节点?
首先在导出代码的时候一旦遇到有脚本的节点就返回。持续遍历其余子节点。这样你的脚本里就不会申明其余脚本要申明的内容。
而后在绑定的时候首先会找到应该做数据绑定的脚本,而后再深刻遍历,当你发现你解决的这个节点上有脚本的时候就会用它身上脚本解决它的子节点。所以如果一个节点有多个脚本就只能绑定第一个脚本的数据。
性能介绍
- 依据预制体文件生成脚本
- 自定义输出目录和输入目录
- 主动绑定属性+数组
应用$V标识变量
应用$A标识数组
属性名称默认带有类型。
- 主动绑定button事件
- 可扩大导出属性类型
- 主动绑定其余预制体的属性,和button事件
- 主动导入应用到的其余脚本
手懒不想本人实现的能够关注公众号,进入微店购买。
欢送扫码关注公众号《微笑游戏》,浏览更多内容。
欢送扫码关注公众号《微笑游戏》,浏览更多内容。