一、什么是装饰器?
装饰器是TypeScript脚本语言中的概念。
TypeScript的解释:在一些场景下,我们需要额外的特性来支持标注或修改类及其成员。装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。
在TypeScript中,装饰器分为:类装饰器、属性装饰器、方法装饰器、方法参数装饰器。
由此可知:
大家都知道,从Cocos Creator3.x 开始,开发语言主要是:TypeScript,那么装饰器也是需要必须理解的。
二、CocosCreator 的装饰器
在理解CocosCreator 的装饰器之前,我们需要先了解几个知识点:CocosCreator序列化、Cocos Creator 的脚本编译时机 、CocosCreator装饰器执行时机。
CocosCreator compile
,执行即可编译。感兴趣的朋友请前往查看CocosCreator3.8研究笔记(二)windows环境 VS Code 编辑器的配置。
1、CC 类
(1)、什么是cc类?
将ccclass 关键词做为注解,添加在类上时,这个类被称为CC类。
语法如下:
@ccclass('name')
如图,PlayerControl 为cc类:
(2)、CC 类的作用
CC 类注入了控制cocos creator 对该类对象的序列化、编辑器对此类对象的显示。
(3)、CC 类注意事项
CC类的名称是唯一的
不能以 cc.
、internal.
作为前缀,这是 Cocos Creator 的保留类名前缀
没声明 ccclass 的组件类,无法作为组件添加到节点上
当CC类是组件时,Node 可以通过组件类的CC类名查找到该组件
2、组件类装饰器
组件类装饰器只能用来修饰 Component
的子类。
(1)、executeInEditMode
正常情况下,所有组件只会在运行时执行, 在编辑器模式下并不会触发,executeInEditMode
默认值为 false
。
如果需要在编辑器模式下就执行,我们可以将executeInEditMode
设置为’true’,表示允许在编辑器模式下运行。
如下代码:
const { ccclass, executeInEditMode } = _decorator;
@ccclass('Example')
@executeInEditMode(true)
export class Example extends Component {
update (dt: number) {
// 在编辑器下每帧执行
}
}
(2)、requireComponent
requireComponent
参数用来指定当前组件的依赖组件,默认值为 null
。
当组件添加到节点上时,如果依赖的组件不存在,引擎会自动将依赖组件添加到同一个节点,防止脚本出错。
const { ccclass, requireComponent } = _decorator;
@ccclass('Example')
@requireComponent(Sprite)
export class Example extends Component {
}
(3)、executionOrder
executionOrder
用来指定脚本生命周期回调的执行优先级。
该优先级设定只对 onLoad
、onEnable
、start
、update
和 lateUpdate
有效,对 onDisable
和 onDestroy
无效。
const { ccclass, executionOrder } = _decorator;
@ccclass('Example')
@executionOrder(3)
export class Example extends Component {
}
(4)、disallowMultiple
同一节点上只允许添加一个同类型(含子类)的组件,防止逻辑发生冲突,默认值为 false。
const { ccclass, disallowMultiple } = _decorator;
@ccclass('Example')
@disallowMultiple(true)
export class Example extends Component {
}
(5)、menu
@menu(path)
用来将当前组件添加到组件菜单中。
该菜单:是添加在 属性检查器 面板中按下添加组件按钮后的下拉框内。
const { ccclass, menu } = _decorator;
@ccclass('Example')
@menu('foo/bar')
export class Example extends Component {
}
(6)、help
指定当前组件的帮助文档的 URL。
设置完成后,在 属性检查器 中就会出现一个帮助图标,点击即可打开帮助文档的 URL。
const { ccclass, help } = _decorator;
@ccclass('Example')
@help('https://docs.cocos.com/creator/3.8/manual/zh/scripting/decorator.html')
export class Example extends Component {
}
3、属性装饰器(property)
属性装饰器用于控制 Cocos Creator 编辑器中对该属性的序列化、属性检查器 中对该属性的展示等。
属性装饰器 property
可以被应用在 cc 类的属性或访问器上。
(1)、属性编辑器常见属性类型
基础属性:CCInteger、CCFloat、CCBoolean、CCString
cc 类型
数组类型:[CCInteger]、[Node]
当使用基础属性类型或者 cc 类作为数组元素时,将分别以整数数组和节点数组的形式在 属性检查器 中展示。
number
、string
、boolean
,则其类型分别对应 Creator 的CCFloat
、CCString
和 CCBoolean
语法如下:
@property({ type:Node,visible:true})
@property({type:CCInteger,visible:true})
n:number=5;
@property({ type:[Node],visible:true})
下图是脚本文件 PlayerControl.ts 与Creator 编辑器属性检查器中属性展示:
Cocos Creator额外提供几种装饰器可以快速声明 cc 类型。
装饰器 | 对应的 property 写法 |
---|---|
@type(t) | @property(t) |
@integer | @property(CCInteger) |
@float | @property(CCFloat) |
以下声明,可以替代 @property 的写法:
@integer // 声明属性的 cc 类型为整数
index = 0;
@type([Node]) // 声明属性 children 的 cc 类型为 Node 数组
children: Node[] = [];
@type(String) // 警告:不应该使用构造函数 String。等价于 CCString。也可以选择不声明类型
text = '';
(2)、属性检查器中属性的可见性
需要注意的是:不是所有定义的属性装饰器都是可见的,在以下两种情况,是不会显示在属性检查器:
(3)、序列化(serializable)
属性默认情况下都会被序列化,序列化后就会将编辑器中设置好的属性值保存到场景等资源文件中,之后在加载场景时就会自动还原成设置好的属性值。如果不想序列化,可以设置 serializable: false。
@property({ serializable: false })
num = 0;
(4)、override
所有属性都会被子类继承,如果子类要覆盖父类同名属性,需要显式设置 override 参数,否则会有重名警告:
@property({ tooltip: "my id", override: true })
id = "";
(5)、group
当脚本中定义的属性过多且杂时,可通过 group
对属性进行分组、排序,方便管理。
同时还支持对组内属性进行分类。
group
写法包括以下两种:
@property({ group: { name } })
@property({ group: { id, name, displayOrder, style } })
参数 | 说明 |
---|---|
id |
分组 ID,string 类型,是属性分组组号的唯一标识,默认为 default 。 |
name |
组内属性分类的名称,string 类型。 |
displayOrder |
对分组进行排序,number 类型,数字越小,排序越靠前。默认为 Infinity ,表示排在最后面。 若存在多个未设置的分组,则以在脚本中声明的先后顺序进行排序。 |
style |
分组样式,目前支持 tab 和 section 样式。 默认为 tab。 |
(6)、get/set 使用
@property
_num:number=1;
set num(val){
this._num=val;
}
get num(){
return this._num;
}
(7)、Cocos Creator 常用内置属性
@property(Color)
color:Color
@property(Gradient)
gradient = new Gradient();
通过颜色、渐变色、双颜色或双渐变色控制颜色
@property(GradientRange)
gradientRange:GradientRange = new GradientRange();