1

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用

 1 month ago
source link: https://blog.51cto.com/u_16653449/10245369
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用

精选 原创

我们知道,在CocosCreator 节点和组件的修改有两种方法:

  • 属性检查器中的设置
  • 脚本中的动态修改

脚本中动态修改,能实现各种各样的游戏逻辑,例如响应玩家输入,删除、修改、销毁节点或组件。

不过想要实现这些游戏逻辑,需要在脚本中访问这些组件或节点。

一、访问节点

1、获得组件所在的节点

只要在组件方法里访问 this.node 变量。

onLoad() {
        
   let node = this.node;
   node.setPosition(0.0,0.0,0.0);
}

2、获得同一个节点上的其它组件

使用 getComponent 查找需要的组件,传入类型,例如:

this.sprite = this.getComponent(Sprite);

还可以通过传入类名来获取,对于自定义的组件,类名就是脚本的文件名,并且 区分大小写

this.testSprite = this.getComponent("TestSprite");

节点上也有一个 getComponent 方法, 作用一样:

console.log( this.node.getComponent(Label) === this.getComponent(Label) );  // true

如果在节点上找不到组件,getComponent 会返回 null,访问 null 值,会在运行时抛出 “TypeError” 错误,

如果不确定组件是否存在,需要判断一下:

this.label = this.getComponent(Label);
 if (this.label) {
 		this.label.string = "test";
 } else {
 		console.error("this.label is null");
 }

3、属性检查器中设置节点及使用

这里以Node节点为例:

(1)、层级管理器中添加Node 节点,名字为Body

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_笔记

(2)、声明一个 type 为 Node 的属性

@property({type:Node})
private Body = null;

此时,属性检查器中的body节点如下:

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_CocosCreator3.8_02

( 3)、将层级管理器中的Body节点拖入 右侧 属性检查器对应的Node

拖入后,显示如下:

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_CocosCreator3.8_03

这样操作后, Body 属性就会被设置成功,我们可以在脚本里访问 Body。

(4)、在脚本里访问 Body 节点

log('Body==' + this.Body.name);
CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_前端_04

4、属性检查器中设置组件及使用

这里以player组件为例:

(1)、层级管理器中添加一个 main 节点,同时在资源管理器中添加main.ts 脚本 ,

并在属性检查器中,将main.ts 脚本 拖入,绑定在main 节点上。

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_CocosCreator_05

(2)、在main.ts 中添加type为playercontrol的属性

@property({type:PlayerControl})
    private PlayerControl = null;

(3)、将层级管理器中的Player节点拖入 右侧 属性检查器对应的PlayerControl

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_CocosCreator3.8_06

通过以上设置后,我们可以在脚本里访问 PlayerControl。

(4)、在脚本里访问 PlayerControl

这样就不需要再自己调用 getComponent 来获取 PlayerControl。

CocosCreator3.8研究笔记(八)CocosCreator 节点和组件的使用_CocosCreator_07

5、查找子节点

有时场景里面的组件比较多,需要有一个脚本来统一管理,如上的main.ts 的作用。

如果用 属性检查器 来一个一个将它们关联到这个脚本上,工作量就非常大。

为了更好地统一管理这些对象,我们可以把它们放到一个父节点下,然后通过父节点来获得所有的子节点:

let cannons = this.node.children;

还可以通过子节点的名字来获取:

this.node.getChildByName("child name");

如果子节点的层次较深,还可以使用 find根据传入的路径进行逐级查找:

find("a/b/c", this.node);

二、访问已有变量里的值

可以使用 import 来实现脚本的跨文件操作。

每个脚本都能用 import{ } from + 文件名(不含路径) 来获取到对方 exports 的对象。

例如:有一个 utils.ts 脚本

// , now the filename matters
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass("utils")
export class utils extends Component {

    public static utilsNode: any = null;
    public static utilsLabel: any = null;
}

在user.ts 中使用 utils.ts ,访问 utils.utilsNode \utils.utilsNode bi

import { _decorator, Component, Node, Label } from 'cc';
const { ccclass, property } = _decorator;
// this feels more safe since you know where the object comes from
import{utils}from "./utils";

@ccclass("user")
export class user extends Component {
    onLoad() {
        utils.utilsNode = this.node;
        utils.utilsLabel = this.getComponent(Label);
    }
}

三、节点常用接口

1、创建新节点

let node =new Node('a');
node.setPosition(0,0,-10);

2、节点激活与关闭

this.node 访问当前脚本所在节点。

this.node.active 表示该节点 自身的 激活状态,这个节点 当前 是否可被激活则取决于它的父节点。

判断节点当前是否已经激活:

activeInHierarchy
this.node.active = true;

若节点原先就处于 可被激活 状态,修改 active 为 true 就会立即触发激活操作:

  • 在场景中重新激活该节点和节点下所有 active 为 true 的子节点。
  • 该节点和所有子节点上的所有组件都会被启用,它们中的 update 方法之后每帧会执行。
  • 这些组件上如果有 onEnable 方法,这些方法将被执行。

一个节点是关闭状态时,它的所有组件都将被禁用, 它所有子节点,以及子节点上的组件也会跟着被禁用。

3、索引子节点

  • this.node.children:返回节点的所有子节点数组。
  • this.node.children.length:返回节点的子节点数量。

注意:以上两个 API 都只会返回节点的直接子节点,不会返回子节点的子节点。

4、更改节点位置

有以下两种方法:

  • 使用 setPosition 方法:
this.node.setPosition(1, 1, 0);
this.node.setPosition(new Vec3(1, 1, 0))
  • 设置 position 变量:
this.node.position = new Vec3(1, 1, 0);

5、更改节点旋转

this.node.setRotation(90, 90, 0);

通过欧拉角设置本地旋转:

this.node.setRotationFromEuler(90, 90, 0);

6、更改节点缩放

this.node.setScale(1, 1, 0);

7、更改节点的父节点

假设父节点为 parentNode,子节点为 this.node

可以通过以下两种方法调整:

this.node.parent = parentNode;
this.node.removeFromParent();
parentNode.addChild(this.node);

8、克隆节点

克隆节点 通过 instantiate 完成。

import { _decorator, Component, Node,instantiate, director } from 'cc';
const { ccclass, property } = _decorator;

@ccclass("testClone")
export class testClone 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);
    }
}

9、销毁节点

销毁节点 可以使用 node.destroy()node.removeFromParent()

两者的区别:

  • 通过调用 node.destroy() 函数,销毁节点并不会立刻被移除,在当前帧逻辑更新结束后才会执行。
    当一个节点销毁后,该节点就处于无效状态,可以通过 isValid 判断当前节点是否已经被销毁。
  • 通过调用`node.removeFromParent()函数,节点并不会从内存中释放,因为引擎内部仍会持有它的数据。
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass("testDestroy")
export class testDestroy extends Component {

    @property({type:Node})
    private target: Node = null;

    private positionz: number = -20;

    start(){
        // 10秒后销毁节点
        setTimeout(function () {
            this.target.destroy();
          }.bind(this), 10000);
    }
    update(deltaTime: number){
        console.info(this.target.isValid);
        this.positionz += 1*deltaTime;
        if (this.target.isValid) {
            this.target.setPosition(0.0,0.0,this.positionz);
          }
    }
}

总结:

如果一个节点不再使用,直接调用它的 destroy 而不是 removeFromParent,也不需要设置 parentnull,否则会导致内存泄漏。

四、组件常用接口

Component 是所有组件的基类,任何组件都包括如下的常见接口:

  • this.node:该组件所属的节点实例
  • this.enabled:是否每帧执行该组件的 update 方法,同时也用来控制渲染组件是否显示
  • update(deltaTime: number):作为组件的成员方法,在组件的 enabled 属性为 true 时,其中的代码会每帧执行。
  • onLoad():组件所在节点进行初始化时执行。
  • start():会在该组件第一次 update 之前执行,通常用于需要在所有组件的 onLoad 初始化完毕后执行的逻辑。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK