Skip to content

Commit 2d0ebe7

Browse files
authored
Merge pull request #1 from oasis-engine/temp/add-clone-doc
add entity clone doc
2 parents dc49b7c + b20cb7b commit 2d0ebe7

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
* [引擎](structure/engine.md)
99
* [场景](structure/scene.md)
1010
* [实体](structure/entity.md)
11+
* [克隆](structure/entity-clone.md)
1112
* [脚本组件](structure/script.md)
1213
* [资源管理与加载](structure/resource-manager.md)
1314
* 资源系统

structure/entity-clone.md

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# 克隆
2+
3+
# 简介
4+
节点克隆是运行时的常用功能,同时节点克隆也会附带克隆其绑定的组件。例如在初始化阶段根据配置动态创建一定数量相同的实体,然后根据逻辑规则摆放到场景不同的位置。这里会对脚本的克隆细节进行详细讲解。
5+
6+
7+
# 使用
8+
## 实体的克隆
9+
非常简单,直接调用实体的 [clone()]({{book.api}}interfaces/design.iclone.html#clone) 方法即可完成实体以及附属组件的克隆。
10+
```typescript
11+
const cloneEntity = entity.clone();
12+
```
13+
14+
15+
## 脚本的克隆
16+
脚本的本质也是组件,所以当我们调用实体的 [clone()]({{book.api}}interfaces/design.iclone.html#clone) 函数时,引擎不仅会对引擎内置组件进行克隆,还是对自定义脚本进行克隆。引擎内置组件的克隆规则官方已经完成定制,同样我们也将脚本的克隆能力和规则定制开放给了开发者。脚本字段默认的克隆方式为浅拷贝,例如我们对脚本的字段值进行修改后再克隆,克隆后的脚本将保持修改后的值,无需增加任何额外的编码。以下为自定义脚本的克隆案例:
17+
```typescript
18+
// define a custom script
19+
class CustomScript extends Script{
20+
/** boolean type.*/
21+
a:boolean = false;
22+
23+
/** number type.*/
24+
b:number = 1;
25+
26+
/** class type.*/
27+
c:Vector3 = new Vector3(0,0,0);
28+
}
29+
30+
//init entity and script.
31+
const entity = engine.createEntity();
32+
const script = entity.addComponent(CustomScript);
33+
script.a = true;
34+
script.b = 2;
35+
script.c.setValue(1,1,1);
36+
37+
// clone logic.
38+
const cloneEntity = entity.clone();
39+
const cloneScript = cloneEntity.getComponent(CustomScript);
40+
console.log(cloneScript.a);// output is true.
41+
console.log(cloneScript.b);// output is 2.
42+
console.log(cloneScript.c);// output is (1,1,1).
43+
```
44+
### 克隆装饰器
45+
除了默认的克隆方式外,引擎还提供了“克隆装饰器“对脚本字段的克隆方式进行定制。引擎内置四种克隆装饰:
46+
47+
| 装饰器名称 | 装饰器释义 |
48+
| :--- | :--- |
49+
| [ignoreClone]({{book.api}}modules/core.html#ignoreclone) | 克隆时对字段进行忽略。 |
50+
| [assignmentClone]({{book.api}}modules/core.html#assignmentclone) | ( 默认值,和不添加任何克隆装饰器等效) 克隆时对字段进行赋值。如果是基本类型则会拷贝值,如果是引用类型则会拷贝其引用地址。 |
51+
| [shallowClone]({{book.api}}modules/core.html#shallowclone) | 克隆时对字段进行浅克隆。克隆后会保持自身引用独立,并使用赋值的方式克隆其内部所有字段(如果内部字段是基本类型则会拷贝值,如果内部字段是引用类型则会拷贝其引用地址)。|
52+
| [deepClone]({{book.api}}modules/core.html#deepClone) | 克隆时对字段进行深克隆。克隆后会保持自身引用独立,并且其内部所有深层字段均保持完全独立。|
53+
54+
我们将上面的案例稍加修改,分别对 `CustomScript` 中的四个字段添加了不同的“克隆装饰器“,由于 `shallowClone` 和 `deepCone`  较复杂,我们对字段 `c` 和 `d` 增加了额外的打印输出进行进一步讲解。
55+
```typescript
56+
// define a custom script
57+
class CustomScript extends Script{
58+
/** boolean type.*/
59+
@ignoreClone
60+
a:boolean = false;
61+
62+
/** number type.*/
63+
@assignmentClone
64+
b:number = 1;
65+
66+
/** class type.*/
67+
@shallowClone
68+
c:Vector3[] = [new Vector3(0,0,0)];
69+
70+
/** class type.*/
71+
@deepClone
72+
d:Vector3[] = [new Vector3(0,0,0)];
73+
}
74+
75+
//init entity and script.
76+
const entity = engine.createEntity();
77+
const script = entity.addComponent(CustomScript);
78+
script.a = true;
79+
script.b = 2;
80+
script.c[0].setValue(1,1,1);
81+
script.d[0].setValue(1,1,1);
82+
83+
// clone logic.
84+
const cloneEntity = entity.clone();
85+
const cloneScript = cloneEntity.getComponent(CustomScript);
86+
console.log(cloneScript.a);// output is false,ignoreClone will ignore the value.
87+
console.log(cloneScript.b);// output is 2,assignmentClone is just assignment the origin value.
88+
console.log(cloneScript.c[0]);// output is Vector3(1,1,1),shallowClone clone the array shell,but use the same element.
89+
console.log(cloneScript.d[0]);// output is Vector3(1,1,1),deepClone clone the array shell and also clone the element.
90+
91+
cloneScript.c[0].setValue(2,2,2);// change the field c[0] value to (2,2,2).
92+
cloneScript.d[0].setValue(2,2,2);// change the field d[0] value to (2,2,2).
93+
94+
console.log(script.c[0]);// output is (2,2,2). bacause shallowClone let c[0] use the same reference with cloneScript's c[0].
95+
console.log(script.d[0]);// output is (1,1,1). bacause deepClone let d[0] use the different reference with cloneScript's d[0].
96+
```
97+
注意:
98+
99+
- `shallowClone` 和 `deepClone` 适用于 *Obect**Array**Class* 类型。
100+
- `shallowClone` 克隆后会保持自身引用独立,并使用赋值的方式克隆其内部所有字段(如果内部字段是基本类型则会拷贝值,如果内部字段是引用类型则会拷贝其引用地址)。
101+
- `deepClone` 如果在深克隆过程中遇到 *Class* 则会调用对象的 [cloneTo()]({{book.api}}interfaces/design.iclone.html#cloneTo) 实现克隆,需要对象实现 [IClone]({{bool.api}}interfaces/design.iclone.html) 接口。

0 commit comments

Comments
 (0)