装饰器使用

    ccclass 装饰器的参数 name 指定了 cc 类的名称,cc 类名是 独一无二 的,这意味着即便在不同目录下的同名类也是不允许的。当需要获取相应的 cc 类时,可以通过其 cc 类名来查找,例如:

    • 序列化。若对象是 cc 类对象,则在序列化时将记录该对象的 cc 类名,反序列化时将根据此名称找到相应的 cc 类进行序列化。

    • 当 cc 类是组件类时,Node 可以通过组件类的 cc 类名查找该组件。

    此类装饰器是只能用来修饰 Component 的子类。

    默认情况下,所有组件都只会在运行时执行,也就是说它们的生命周期回调在编辑器模式下并不会触发。executeInEditMode 允许当前组件在编辑器模式下运行,默认值为 false

    1. const { ccclass, executeInEditMode } = _decorator;
    2. @ccclass('Example')
    3. @executeInEditMode(true)
    4. export class Example extends Component {
    5. update (dt: number) {
    6. // 会在编辑器下每帧执行
    7. }
    8. }

    requireComponent

    requireComponent 参数用来指定当前组件的依赖组件,默认值为 null。当组件添加到节点上时,如果依赖的组件不存在,引擎会自动将依赖组件添加到同一个节点,防止脚本出错。该选项在运行时同样有效。

    1. const { ccclass, requireComponent } = _decorator;
    2. @ccclass('Example')
    3. @requireComponent(Sprite)
    4. export class Example extends Component {
    5. }

    executionOrder

    executionOrder 用来指定脚本生命周期回调的执行优先级。小于 0 的脚本将优先执行,大于 0 的脚本将最后执行。排序方式如下:

    • 对于同一节点上的不同组件,数值小的先执行,数值相同的按组件添加先后顺序执行
    • 对于不同节点上的同一组件,按节点树排列决定执行的先后顺序

    该优先级设定只对 onLoadonEnablestartupdatelateUpdate 有效,对 onDisableonDestroy 无效。

    1. const { ccclass, executionOrder } = _decorator;
    2. @ccclass('Example')
    3. @executionOrder(3)
    4. export class Example extends Component {
    5. }

    同一节点上只允许添加一个同类型(含子类)的组件,防止逻辑发生冲突,默认值为 false。

    1. const { ccclass, disallowMultiple } = _decorator;
    2. @ccclass('Example')
    3. @disallowMultiple(true)
    4. export class Example extends Component {
    5. }

    menu

    @menu(path) 用来将当前组件添加到组件菜单中,方便用户查找。

    1. const { ccclass, menu } = _decorator;
    2. @ccclass('Example')
    3. @menu('foo/bar')
    4. }

    help

    指定当前组件的帮助文档的 URL。设置完成后,在 属性检查器 中就会出现一个帮助图标,点击即可打开指定的网页。

    1. const { ccclass, help } = _decorator;
    2. @ccclass('Example')
    3. @help('https://docs.cocos.com/creator/3.5/manual/zh/scripting/decorator.html')
    4. export class Example extends Component {
    5. }

    属性装饰器 property 可以被应用在 cc 类的属性或访问器上。属性装饰器用于控制 Cocos Creator 编辑器中对该属性的序列化、属性检查器 中对该属性的展示等。

    属性装饰器的各种特性是通过 @property() 的参数来指定的。完整可选择参数可以参考:属性参数

    property 装饰器写法参考如下:

    接着,下方会罗列出一些常用属性参数写法。

    选项 type 指定了属性的 cc 类型。可以通过以下几种形式的参数指定类型:

    • 基础属性类型

      CCFloatCCBooleanCCString 是基础属性类型标识,一般仅用于数组属性的内部类型声明。非数组类型不需要显式声明这些类型。

      • CCInteger 声明类型为 整数
      • CCFloat 声明类型为 浮点数
      • CCString 声明类型为 字符串
      • CCBoolean 声明类型为 布尔值
    • 所有的 cc 类型 都需要显式指定,否则编辑器无法正确识别类型,序列化也无法写入正确类型。

    • 数组类型

      当使用基础属性类型或者 cc 类作为数组元素时,可以被通过数组类型声明被编辑器所识别。例如 [CCInteger][Node] 将分别以整数数组和节点数组的形式在 属性检查器 中展示。

    若属性未指定类型,Cocos Creator 将从属性的默认值或初始化式的求值结果推导其类型:

    • 若值的类型是 JavaScript 原始类型 numberstringboolean,则其类型分别对应 Creator 的CCFloatCCStringCCBoolean
    • 其他情况下属性的类型则是 未定义 的,编辑器上会提示 Type(Unknown) 字样。

    下列代码演示了不同 cc 类型的属性声明:

    1. import { _decorator, CCInteger, Node, Enum } from 'cc';
    2. const { ccclass, property, integer, float, type } = _decorator;
    3. enum A {
    4. c,
    5. d
    6. }
    7. Enum(A);
    8. @ccclass
    9. class MyClass {
    10. @property // JavaScript 原始类型,根据默认值自动识别为 Creator 的浮点数类型。
    11. index = 0;
    12. @property(Node) // 声明属性 cc 类型为 Node。当属性参数只有 type 时可这么写,等价于 @property({type: Node})
    13. targetNode: Node | null = null; // 等价于 targetNode: Node = null!;
    14. // 声明属性 children 的 cc 类型为 Node 数组
    15. @property({
    16. type: [Node]
    17. })
    18. children: Node[] = [];
    19. @property({
    20. type: String,
    21. }) // 警告:不应该使用构造函数 String。等价于 CCString。也可以选择不声明类型
    22. text = '';
    23. @property
    24. children2 = []; // 未声明 cc 类型,从初始化式的求值结果推断元素为未定义的数组
    25. @property
    26. _valueB = 'abc'; // 此处 '_' 开头的属性,只序列化,不会在编辑器属性面板显示
    27. @property({ type: A })
    28. }

    为了方便,额外提供几种装饰器以快速声明 cc 类型。如果你只需要为属性定义 type 参数,那么可以直接使用下列装饰器替代 :

    1. import { _decorator, CCInteger, Node } from 'cc';
    2. const { ccclass, property, integer, float, type } = _decorator;
    3. @ccclass
    4. class MyClass {
    5. @integer // 声明属性的 cc 类型为整数
    6. index = 0;
    7. @type([Node]) // 声明属性 children 的 cc 类型为 Node 数组
    8. children: Node[] = [];
    9. @type(String) // 警告:不应该使用构造函数 String。等价于 CCString。也可以选择不声明类型
    10. text = '';
    11. // JavaScript 原始类型 `number`、`string`、`boolean` 通常可以不用声明
    12. // 可以直接写
    13. @property
    14. text = '';
    15. }

    visible

    一般情况下,属性是否显示在 属性检查器 中取决于属性名是否以 _ 开头。如果是以 _ 开头,则不显示

    如果要强制显示在 属性检查器 中,可以设置 visible 参数为 true:

    1. @property({ visible: true })
    2. private _num = 0;

    如果要强制隐藏,可以设置 visible 参数为 false:

    1. @property({ visible: false })
    2. num = 0;

    serializable

    属性默认情况下都会被序列化,序列化后就会将编辑器中设置好的属性值保存到场景等资源文件中,之后在加载场景时就会自动还原成设置好的属性值。如果不想序列化,可以设置 serializable: false

    1. @property({ serializable: false })
    2. num = 0;

    所有属性都会被子类继承,如果子类要覆盖父类同名属性,需要显式设置 override 参数,否则会有重名警告:

    1. @property({ tooltip: "my id", override: true })
    2. id = "";

    group

    当脚本中定义的属性过多且杂时,可通过 group 对属性进行分组、排序,方便管理。同时还支持对组内属性进行分类。

    group 写法包括以下两种:

    • @property({ group: { name } })

    • @property({ group: { id, name, displayOrder, style } })

    参数说明
    id分组 ID,string 类型,是属性分组组号的唯一标识,默认为 default
    name组内属性分类的名称,string 类型。
    displayOrder对分组进行排序,number 类型,数字越小,排序越靠前。默认为 Infinity,表示排在最后面。
    若存在多个未设置的分组,则以在脚本中声明的先后顺序进行排序
    style分组样式,目前只支持 tab 样式。

    示例脚本如下:

    decorator-group

    因为分组一未指定 displayOrder,分组二指定了 displayOrder 为 1,所以分组二会排在分组一的前面。

    若需要对分组内的属性排序,也可以使用 displayOrder。以分组二为例,目前是按照在脚本中定义的先后顺序进行排序,label2 在 sprite2 的前面。我们将其调整为:

    1. // 分组二
    2. // 组内名为 “bar” 的属性分类,其中包含名为 label2 的 Label 属性和名为 sprite2 的 Sprite 属性,并且指定排序为 1。
    3. @property({ group: { name: 'bar2', id: '2', displayOrder: 1 }, displayOrder: 2, type: Label })
    4. label2: Label = null!;
    5. @property({ group: { name: 'bar2', id: '2' }, displayOrder: 1, type: Sprite })
    6. sprite2: Sprite = null!;

    回到编辑器,在 属性检查器 中可以看到 sprite2 已经排在 label2 的前面了:

    针对一些常用类型,引擎内部提供了默认界面,开发者可以根据自身的需求使用:

    • 颜色界面:

      color

      代码示例如下:

      1. @property(Color)
      2. color:Color
    • 曲线:用于保存曲线类型、样式以及采样数据。

      代码示例如下:

      1. @property(RealCurve)
      2. realCurve:RealCurve = new RealCurve();
    • 曲线范围:可以通过常量、曲线、双曲线或双常量进行控制。

      color

      代码示例如下:

      1. @property(CurveRange)
      2. curveRang : CurveRange = new CurveRange();
    • 渐变色:记录渐变色的关键值和用于计算渐变色的结果

      代码示例如下:

      1. @property(Gradient)
      2. gradient = new Gradient();
    • 渐变色范围:通过颜色、渐变色、双颜色或双渐变色控制颜色

      代码示例如下:

      1. gradientRange:GradientRange = new GradientRange();