CCClass
When the decorator ccclass is applied to a class, the class is called ccclass
. The ccclass
injects additional information to control Cocos Creator 3.0's serialization of this kind of object along with the editor's display for these types of objects.
ccclass
Various characteristics of the ccclass
are specified by the ccclass
option parameter of ccclass(name)
.
ccclass name
The option name
specifies the name of the ccclass
. The ccclass
name should be unique.
When you need the corresponding ccclass
, you can find it by its ccclass
name, for example:
Serialization. If the object is a cc object, the
ccclass
name of the object will be recorded during serialization. During deserialization, the correspondingccclass
will be found for serialization based on this name.When the
ccclass
is a component class,Node
can find the component by itsccclass
name.
Property decorators
When the decorator property is applied to a property or accessor of the ccclass
, this property is called a ccproperty
.
Similar to the ccclass
, the ccattribute
injects additional information to control the serialization of the property in Cocos Creator 3.0 and the display of the property in the editor.
Property
Various characteristics of the ccattribute
are specified by the ccproperty
option parameter of property()
.
cctype
The option type
specifies the cctype
of the property. The type can be specified by the following parameters:
Constructor
The type specified by the constructor is directly used as the
cctype
of the property.Note: when Javascript built-in constructors
Number
,String
,Boolean
A warning will be given when used as acctype
, and they are regarded ascctype
'sCCFloat
,CCString
, andCCBoolean
respectively.Cocos Creator 3.0 built-in attribute type identification.
CCInteger
,CCFloat
,CCBoolean
, andCCString
are built-in property type identifiers.CCInteger
declares the type as integer.CCFloat
declares the type as floating point number.CCString
declares the type as string.CCBoolean
declares the type as Boolean.
Array
When using the constructor, built-in property type identification or array as the array element, the properties are specified as Cocos Creator 3.0 array. For example,
[CCInteger]
declares the type as a array whose elements are integers.
If the property does not specify the cctype
, Cocos Creator 3.0 will derive its cctype
from the default value of the property or the evaluation result of the initialization formula:
- If the value type is Javascript primitive type
number
,string
,boolean
, thecctype
s are Creator floating point, string, and boolean values, respectively. - Otherwise, if the value is an object type, it is equivalent to using the object's constructor to specify the
cctype
. - Otherwise, the
cctype
of the property is undefined.
Generally, you only need to explicitly declare the cctype
in the following situations:
- When the property needs to be displayed as an integer.
- When the actual value of the property may be of multiple types.
For how the cctype
affects the cc property and the treatment of properties that do not define the cctype
, see:
For convenience, the following decorators are additionally provided to quickly declare the cctype
:
Type | Equivalent to |
---|---|
@type(t) | @property(t) |
@integer | @property(CCInteger) |
@float | @property(CCFloat) |
@string | @property(CCString) |
@boolean | @property(CCBoolean) |
The following code demonstrates the declaration of ccattributes
of different cctype
s:
import { _decorator, CCInteger, Node } from 'cc';
const { ccclass, property, integer, float, boolean, string, type } = _decorator;
@ccclass
class MyClass {
@integer // Declare that the cc type of the property _id is a Cocos integer
private _id = 0;
@type(Node) // Declare that the cc type of the property _targetNode is Node
private _targetNode: Node | null = null;
@type([Node]) // declare the cc type of the property _children as a Node array
private _children: Node[] = [];
@property
private _count = 0; // the cc type is not declared, and it is inferred from the evaluation result of the initializer as a Cocos floating point number
@type(String) // Warning: Constructor should not be used String
// equivalent to CCString
private _name: string = '';
@property
private _children2 = []; // The cc type is not declared, inferred from the evaluation result of the initializer: the element is an undefined Cocos array
}
Defaults
The option default
specifies the default value of the cc
property.
Constructor
Defined By Constructor
The constructor of CCClass
is defined by constructor
. To ensure that deserialization can always run correctly, constructor
is not allowed to define constructor parameters.
Note: if developers really need to use construction parameters, they can get them through
arguments
, but remember that if this class will be serialized, you must ensure that the object can still be new when the construction parameters are all default.
Judging The Type
Judgment Example
When making type judgments, use TypeScript native instanceof
:
class Sub extends Base {
}
let sub = new Sub();
console.log(sub instanceof Sub); // true
console.log(sub instanceof Base); // true
let base = new Base();
console.log(base instanceof Sub); // false
Members
Instance Variables
The instance variables defined in the constructor cannot be serialized, nor can they be viewed in the Inspector panel.
class Sprite {
// Declare variables
url: string;
id: number;
constructor() {
// assignment
this.url = "";
this.id = 0;
}
}
Note: if it is a private variable, it is recommended to add an underscore
_
in front of the variable name to distinguish it.
Example Method
Please declare the instance method in the prototype object:
class Sprite {
text: string;
constructor() {
this.text = "this is sprite"
}
// Declare an instance method named "print"
print() {
console.log(this.text);
}
}
let obj = new Sprite();
// call instance method
obj.print();
Static Variables and Static Methods
Static variables or static methods can be declared with static
:
class Sprite {
static count = 0;
static getBounds() {
}
}
Static members will be inherited by subclasses. When inheriting, the static variables of the parent class will be shallowly copied to the subclass. Therefore:
class Object {
static count = 11;
static range: { w: 100, h: 100 }
}
class Sprite extends Object {
}
console.log(Sprite.count); // The result is 11 because count inherits from the Object class
Sprite.range.w = 200;
console.log(Object.range.w); // The result is 200, because Sprite.range and Object.range point to the same object
If you don't need to consider inheritance, private static members can also be defined directly outside the class:
// local method
doLoad(sprite) {
// ...
};
// local variables
let url = "foo.png";
class Sprite {
load() {
this.url = url;
doLoad(this);
};
};
Inheritance
Parent Constructor
Please note that regardless of whether the subclass has a constructor defined, the constructor of the parent class will be automatically called before the subclass is instantiated.
class Node {
name: string;
constructor() {
this.name = "node";
}
}
class Sprite extends Node {
constructor() {
super();
// Before the child constructor is called, the parent constructor has been called, so this.name has been initialized
console.log(this.name); // "node"
// Reset "this.name"
this.name = "sprite";
}
}
let obj = new Sprite();
console.log(obj.name); // "sprite"
Rewrite
All member methods are virtual methods, and child methods can directly override parent methods:
class Shape {
getName() {
return "shape";
}
};
class Rect extends Shape {
getName () {
return "rect";
}
};
let obj = new Rect();
console.log(obj.getName()); // "rect"
Properties
Properties are special instance variables that can be displayed in the Inspector panel and can also be serialized.
Properties and Constructors
The property not required is defined in the constructor. Before the constructor is called, the property has been assigned a default value and can be accessed in the constructor. If the default value of the property cannot be provided when defining the ccclass
and needs to be obtained at runtime, you can also re-assign the default value to the property in the constructor.
class Sprite {
constructor() {
this.num = 1;
}
@property({ type: CCInteger })
private num = 0;
}
However, it should be noted that the process of property deserialization occurs immediately after the execution of the constructor, so the default value of the property can only be obtained and modified in the constructor, and it cannot be obtained and saved before the modification (serialization ) value.
Property Parameters
Default Parameter
default
is used to declare the default value of the property. The property with the default value will be implemented as a member variable by ccclass
. The default value is only used when the object is created for the first time, which means that when the default value is modified, the current value of the component that has been added to the scene will not be changed.
Note: after you add a component to the editor, go back to the script to modify a default value, there is no change in the Inspector panel. Because the current value of the property has been serialized into the scene, it is no longer the default value used when it was first created. If you want to force all properties to be reset to default values, you can select Reset in the component menu of the Inspector panel.
default
can be set to the following value types:
- Any number, string or boolean type value
null
orundefined
Subclasses inherited from
ValueType
, such as instantiated objects ofVec3
,Color
orRect
:@property({ type: Vec3 }) private pos = null;
Empty array
[]
or empty object{}
visible
By default, whether it is displayed in the Inspector panel depends on whether the property name starts with an underscore _
. If it starts with an underscore, it will not be displayed in the Inspector panel by default, otherwise it will be displayed by default.
If you want to force it to be displayed in the Inspector panel, you can set the visible
parameter to true:
@property({ visible: true })
private _num = 0;
If you want to force hiding, you can set the visible
parameter to false:
@property({ visible: false })
private num = 0;
serializable
Properties with a default value of default
will be serialized by default. After serialization, the values set in the editor will be saved to resource files such as scenes, and the previously set values will be automatically restored when the scene is loaded. If you don't want to serialize, you can set serializable: false
.
@property({ serializable: false })
private num = 0;
type
When default
cannot provide enough detailed type information, in order to display the correct input control in the Inspector panel, you must use type
to explicitly declare the specific type:
When the default value is null, set type to the constructor of the specified type, so that the Inspector panel knows that a Node control should be displayed.
@property({ type: Node }) private enemy = null;
When the default value is a number type, set the type to
cc.Integer
to indicate that this is an integer, so that the property cannot be entered in the decimal point in the Inspector panel.@property({ type: CCInteger }) private num = 0;
When the default value is an enumeration (
Enum
), since the enumeration value itself is actually a number, the type must be set to the enumeration type to be displayed in the Inspector panel enumerate the drop-down box.enum A { c, d } Enum(A); @ccclass("test") export class test extends Component { @property({ type: A }) accx:A=A.c; }
override
All properties will be inherited by the subclass. If the subclass wants to override the property with the same name of the parent class, you need to explicitly set the override parameter, otherwise there will be a duplicate name warning:
@property({ type: CCString, tooltip: "my id", override: true })
private _id = "";
@property({ displayName: "Name", override: true })
private _name = null;
private get name() {
return this._name;
}
group
If there are many properties or mixed properties defined in the script, the properties can be grouped and sorted by group
for easy management. It also supports sorting properties within a group.
@property({ group: { name } })
@property({ group: { id, name, displayOrder, style } })
Property | Description |
---|---|
id |
Group ID, string type, is a unique identifier for the property group, and defaults to default . |
name |
The name to classify the properties in the group, string type. |
displayOrder |
Sort the groups, number type. The smaller the number, the higher the sorting. The default is Infinity , which means the group is sorted last.If there are multiple groups without displayOrder set, they will be sorted in the order declared in the script. |
style |
Grouping styles, currently only tab styles are supported. |
Example script is as follows:
import { _decorator, Component, Label, Sprite } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('SayHello')
export class SayHello extends Component {
// Group 1
// The property category named "bar" within the group, which contains a Label property named "label".
@property({ group: { name: 'bar' }, type: Label })
label: Label = null!;
// The property category named "foo" within the group, which contains a Sprite property named "sprite".
@property({ group: { name: 'foo' }, type: Sprite })
sprite: Sprite = null!;
// Group 2
// The property category named "bar2" within the group, which contains a Label property named "label2" and a Sprite property named "sprite2".
@property({ group: { name: 'bar2', id: '2', displayOrder: 1 }, type: Label })
label2: Label = null!;
@property({ group: { name: 'bar2', id: '2' }, type: Sprite })
sprite2: Sprite = null!;
}
Mounting the script to the node displays the following image in the Inspector panel:
Because group 1 does not specify displayOrder
and group 2 specifies displayOrder
as 1
, group 2 will be ranked ahead of group 1.
Sorting the properties within a group can also be done via displayOrder
. Taking group 2 as an example, it is currently sorted in the order defined in the script, with label2 in front of sprite2. Let's adjust it to:
// Group 2
@property({ group: { name: 'bar2', id: '2', displayOrder: 1 }, displayOrder: 2, type: Label })
label2: Label = null!;
@property({ group: { name: 'bar2', id: '2' }, displayOrder: 1, type: Sprite })
sprite2: Sprite = null!;
Back to the editor, the sprite2 is now in front of label2 in the Inspector panel:
For additional information about the properties, please refer to the Properties documentation.
get/set methods
After the get
or set
is set in the property, when the property is accessed, the predefined get
or set
method can be triggered.
get
Set the get
method in the properties:
private _num = 0;
@property({ type: CCInteger })
private get num() {
return this._num;
}
The get method can return any type of value.
This property can also be displayed in the Inspector panel and can be directly accessed in all codes including the constructor.
class Sprite {
_width: number;
constructor() {
this._width = 128;
console.log(this.width); // 128
}
@property({ type: CCInteger })
private width = 0;
private get width() {
return this._width;
}
};
As get accessor is used, this property cannot be serialized, nor can it be assigned a default value, but most parameters except default
and serializable
can still be attached.
@property({ type: CCInteger, tooltip: "The width of sprite" })
private _width = 0;
private get width() {
return this._width;
}
The get
accessor is read-only, but the returned object is not read-only. Users can still modify the internal properties of the object using code, for example:
@property
_num = 0;
private get num() {
return this._num;
}
start() {
consolo.log(this.num);
}
set
Set the set
method in the properties:
private _width = 0;
@property({ type: CCInteger })
set (value) {
this._width = value
}
The set
method receives an incoming parameter, which can be of any type.
set
is generally used with get
:
@property
_width = 0;
private get width() {
return this._width;
}
set(value) {
this._width = value;
}
Notes:
- If it is not defined together with
get
, theset
itself cannot be accompanied by any parameters.- Like
get
, afterset
is set, this property cannot be serialized, nor can it be assigned a default value.