Cocos Creator3.x 必备技能-装饰器

前言

在使用Cocos Creator工具开发时,属性检查器面板是我们最常用到的功能面板。

便捷的操作让我们的开发更加的省力。那么在使用的同时小伙伴们有没有想过他的实现原理呢,自己是否可以实现出相同的效果呢!
如何将自定义的class也显示到属性检查器面板中呢!

最近菜鸟在开发中使用到了Cocos Creator的装饰器来与Inspector面板结合实现,菜鸟周末花了点时间大概整理了一下,长话短说,直接见正文。

正文

1.TypeScript装饰器

首先咱们来了解一下TypeScript对装饰器的解释:在一些场景下我们需要额外的特性来支持标注或修改类及其成员。 装饰器(Decorators)为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。
从上边的解释中 我们可以提取到几个关键点:

  • 作用:标注或修改类及其成员
  • 作用目标:类及其成员(类,方法, 访问符,属性或参数)

继续往下了解,我们可以了解到TypeScript装饰器大概存在:类装饰器,属性装饰器,方法装饰器,方法参数装饰器这几种。有关TypeScript装饰器的相关内容,小伙伴们可以自己百度奥。

2.Cocos Creator 中的装饰器

这才是咱们今天讨论的重点。

从Cocos Creator3.x 编程语言TypeScript成为其主要的开发语言开始,装饰器就成了大家必须要了解的,菜鸟在多次面试过程中也被问到了。
大家可以先了解一下序列化 Cocos Creator 的脚本编译时机装饰器执行时机

  • **序列化:**默认情况会将编辑器中设置好的属性值保存到场景等资源文件中,之后在加载场景时就会自动还原成设置好的属性值。
  • **脚本编译时机:**小伙伴们可能都发现了,我们在外部脚本编辑器修改项目脚本后,重新返回 Cocos Creator 会自动的触发脚本编译。
  • 装饰器执行时机:修饰器对类的行为的改变,是代码编译时发生的(不是TypeScript编译,而是js在执行机中编译阶段),而不是在运行时。这意味着,修饰器能在编译阶段运行代码。也就是说,修饰器本质就是编译时执行的函数。

1.基本用法

组件类装饰器(executeInEditMode)

正常情况下,所有组件都只会在运行时执行,也就是说它们的生命周期回调在编辑器模式下并不会触发。如果需要在编辑器模式下就执行,可以使用组件类装饰器

属性装饰器(property)

属性编辑器的常见属性类型:

  • 基础属性:CCInteger、CCFloat、CCBoolean、CCString
  • cc 类型
  • 数组类型:[CCInteger]、[Node]
可见性

需要注意的是:不是所有定义的属性装饰器都是可见的。在以下两种情况,是不会显示在编辑器子中的:

  • 属性名是否以 _ 开头
  • visible属性值为false
序列化(serializable)

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

@property({ serializable: false })
num = 0;
get/set 使用
@property
_num:number=1;
@property({type:CCInteger,tooltip:"提示内容"})
set num(val){
    this._num=val;
}
get num(){
    return this._num;
}

以上内容将一些简单的,最常用的基本用法进行介绍,详细内容可以自行参考官方文档。

2.更多用法

下拉列表

滑动条

@property({type:CCFloat,slide:true,max:1.0,min:0.0,step:0.01})
slide:number=0.5;

自定义样式

样式1

样式2

样式3

enum Type {
    one = 1,
    two = 2,
    three = 3,
    four = 4,
    five = 5,
}
Enum(Type);
@ccclass('Test4')
@executeInEditMode(true)
export class Test4 extends Component {
    @property
    _type: Type = Type.one;
    @property({ type: Type })
    get type() {
        return this._type;
    }
    set type(val) {
        this._type = val;
        this.setType(val);
    }
    @property
    _num: number = 10;
    @property({
        type: CCInteger, visible: function (this) {
            return this.isShowNum;
        }
    })
    get num() {
        return this._num;
    }
    set num(val) {
        this._num = val;
    }
    @property
    _str: string = "你好";
    @property({
        visible: function (this) {
            return this.isShowString;
        }
    })
    get str() {
        return this._str;
    }
    set str(val) {
        this._str = val;
    }

    @property
    _bool: boolean = true;
    @property({
        visible: function (this) {
            return this.isShowBool;
        }
    })
    get bool() {
        return this._bool;
    }
    set bool(val) {
        this._bool = val;
    }
    private isShowNum = false;
    private isShowString = false;
    private isShowBool = false;
    private setType(val): void {
       ...
    }

    onLoad() {
        console.log("onLoad");
    }
}

demo 链接

公众号回复:“装饰器”

往期内容

16赞

感谢分享!

2.0也可以用吧

嗯嗯,对的

超棒的分享!

1赞