简介
instantiate方法在Cocos Creator中有两种作用:
- 从 Prefab 实例化出新节点
- 克隆指定的任意类型的对象
对应于框架源代码中的文字介绍如下:
/**
* @zh 从 Prefab 实例化出新节点。
* @en Instantiate a node from the Prefab.
* @param prefab The prefab.
* @returns The instantiated node.
* @example
* ```ts
* import { instantiate, director } from 'cc';
* // Instantiate node from prefab.
* const node = instantiate(prefabAsset);
* node.parent = director.getScene();
* ```
*/
export function instantiate(prefab: Prefab): Node;
/**
* @en Clones the object `original.
* @zh 克隆指定的任意类型的对象。
* @param original An existing object that you want to make a copy of.
* It can be any JavaScript object(`typeof original === 'object'`) but:
* - it shall not be array or null;
* - it shall not be object of `Asset`;
* - if it's an object of `CCObject`, it should not have been destroyed.
* @returns The newly instantiated object.
* @example
* ```ts
* import { instantiate, director } from 'cc';
* // Clone a node.
* const node = instantiate(targetNode);
* node.parent = director.getScene();
* ```
*/
export function instantiate<T>(original: T): T;
export namespace instantiate {
export var _clone: typeof __private._cocos_serialization_instantiate__doInstantiate;
export var _clone: typeof __private._cocos_serialization_instantiate__doInstantiate;
}
从 Prefab 实例化出新节点
和克隆已有节点相似,你可以设置一个预制(Prefab)并通过 instantiate
生成节点。使用方法如下:
import { _decorator, Component, Prefab, instantiate, director } from 'cc';
const { ccclass, property } = _decorator;
@ccclass("test")
export class test extends Component {
@property({type:Prefab})
private target: Prefab = null;
start(){
let scene = director.getScene();
let node = instantiate(this.target);
scene.addChild(node);
node.setPosition(0,0,0);
}
}
需要注意的是,在使用上述的代码时,需将持有该代码的脚本挂在某个节点上,并在 属性检查器 内配置好 target
的值。
操作Prefab对象数组的举例
注:本例程改编自官方示例工程中的event-first场景,修改后的代码如下:
import { _decorator, Component, Node, instantiate, EventTouch, Prefab, Label, Button,Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('eventFirst')
export class eventFirst extends Component {
@property({
type: Prefab,
})
public prefabNode: Prefab = null!;
@property({
type:Label
})
public labelShow: Label = null!;
@property({
type: Button,
})
public button: Button = null!;
// @property({
// type: Node,
// })
//public items: Node[] = null!;//XXXXXX
public items: Node[] = [];
private static times: number=0;
public i: Node=null!;
onl oad () {
this.i=instantiate(this.prefabNode);
this.items.push(this.i);//TypeError: Cannot read property 'push' of null
eventFirst.times++;
console.log("eventFirst.times: ", eventFirst.times);
}
start () {
// Your initialization goes here.
}
onEnable() {
this.eventOn();
}
eventOn() {
this.i.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
this.i.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
this.i.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
this.i.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
this.node.addChild(this.i);
console.log("addChild(this.i) ");
}
onDisable() {
this.items.forEach(item => {
item.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
item.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
item.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
item.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
});
}
onTouchStart(event: EventTouch){
this.labelShow.string = `TouchStart: ${event.getLocation()}`;
console.log(`TouchStart: ${event.getLocation()}`);
}
onTouchMove(event: EventTouch){
this.labelShow.string = `TouchMove: ${event.getLocation()}`;
console.log(`TouchMove: ${event.getLocation()}`);
}
onTouchEnd(event: EventTouch){
this.labelShow.string = 'TouchEnd';
console.log('TouchEnd');
}
onTouchCancel(event: EventTouch){
this.labelShow.string = 'TouchCancel';
console.log('TouchCancel');
}
createChild() {
console.log("eventFirst.times: ", eventFirst.times++);
let item = instantiate(this.prefabNode);
item.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
item.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
item.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
item.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
let tmpItem=this.items[this.items.length-1];
item.setPosition(new Vec3(tmpItem.position.x+90,
tmpItem.position.y));
this.items.push(item);
this.node.addChild(item);
// this.button.node.active = false;
}
}
这是实战场景中动态创建Prefab对象的方案之一,仅供参考。
克隆指定的任意类型的对象
有时我们希望动态的克隆场景中的已有节点,我们可以通过 instantiate
方法完成。注意事项:
要克隆的JavaScript对象可以是任何JS对象(`typeof original === 'object'`) ,但是:
* 不是能数组或者null。
* 也不是能Asset类型的对象。
*如果是一个CCObject类型的对象,那么被克隆的母对象不能已被销毁。
来自于官方地址的简单应用举例如下:
import { _decorator, Component, Node,instantiate, director } from 'cc';
const { ccclass, property } = _decorator;
@ccclass("test")
export class test extends Component {
@property({type:Node})
private target: Node = null;
start(){
let scene = director.getScene();
let node = instantiate(this.target);
scene.addChild(node);
node.setPosition(0, 0,-10);
}
}
参考
https://docs.cocos.com/creator/manual/zh/scripting/create-destroy.html