Access Nodes and Components

    • Obtain the node where the component is located.
    • Obtain other components.
    • Use Inspector panel to set up nodes and components.
    • Find child nodes.
    • Global node search.
    • Access values in existing variables.

    It’s easy to get the node where the component is. Just access the variable in the component method:

    It will often be need to get other components on the same node. Use the getComponent API, which will help to find the component that is needed.

    1. import { _decorator, Component, LabelComponent } from 'cc';
    2. const { ccclass, property } = _decorator;
    3. @ccclass("test")
    4. export class test extends Component {
    5. private label: any = null
    6. start(){
    7. this.label = this.getComponent(LabelComponent);
    8. let text = this.name + 'started';
    9. // Change the text in Label Component
    10. this.label.string = text;
    11. }
    12. }

    It is also possible to pass in a class name for getComponent. For user-defined components, the class name is the file name of the script and is case sensitive. For example, the component declared in SinRotate.ts, the class name is SinRotate.

    1. let rotate = this.getComponent("SinRotate");

    There is also ther getComponent method on the node, and their functions are the same:

    1. start() {
    2. console.log( this.node.getComponent(LabelComponent) === this.getComponent(LabelComponent) ); // true
    3. }

    If the component that is needed is not found on the node, getComponent will return null. If you try to access the value of null, a TypeError error will be thrown at runtime. If you are not sure whether the component exists, please remember to check:

    1. import { _decorator, Component, LabelComponent } from 'cc';
    2. const { ccclass, property } = _decorator;
    3. @ccclass("test")
    4. export class test extends Component {
    5. private label: any =null;
    6. start() {
    7. this.label = this.getComponent(LabelComponent);
    8. this.label.string = "Hello";
    9. } else {
    10. console.error("Something wrong?");
    11. }
    12. }
    13. }

    It is usually not enough to only have access to the node’s own components, and scripts usually require interaction between multiple nodes. For example, a cannon that automatically aims at the player needs to constantly obtain the latest position of the player. Cocos Creator provides some different methods to obtain other nodes or components.

    This code declares a player property in properties, the default value is null, and its object type is specified as Node. This is equivalent to declaring in other languages. After the script is compiled, this component looks like this in the Inspector panel:

    Then you can drag any node on the Hierarchy panel to the Player control:

    player-in-inspector

    The Player property will be set successfully, and can be accessed directly in a script. Example:

    1. // Cannon.ts
    2. import { _decorator, Component, Node } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. @ccclass("Cannon")
    5. export class Cannon extends Component {
    6. @property({type:Node})
    7. private player = null;
    8. start() {
    9. console.log('The player is ' + this.player.name);
    10. }
    11. }

    In the above example, if the type of the property is declared as a Player component, when the Player node is dragged to the Inspector panel, the Player property will be set to the Player component in this node. This way developers don’t need to call getComponent() themselves.

    1. // Cannon.ts
    2. import { _decorator, Component } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. import { Player } from "Player";
    5. @ccclass("Cannon")
    6. export class Cannon extends Component {
    7. @property({type:Player})
    8. private player = null;
    9. start(){
    10. let PlayerComp = this.player;
    11. }
    12. }

    Sometimes, there are many objects of the same type in the game scene, such as turrets, enemies, and special effects, and they usually have a global script to manage them uniformly. Using the Inspector panel to associate them with this script one by one, the work will be very tedious. In-order to better manage these objects uniformly, they can be put under a unified parent object, and then obtain all the child objects through the parent object:

    1. // CannonManager.ts
    2. import { _decorator, Component, Node } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. @ccclass("CannonManager")
    5. export class CannonManager extends Component {
    6. let cannons = this.node.children;
    7. //...
    8. }
    9. }

    Using getChildByName:

    1. this.node.getChildByName("Cannon 01");

    If the child node has a deeper level, find can be used, and will search step by step according to the path passed in:

    When find only passes in the first parameter, it will be searched step by step from the scene root node:

    1. this.backNode = find("Canvas/Menu/Back");

    If you have saved references to nodes or components in one place, you can also access them directly.

    Use import to implement script cross-file operations. Example:

    1. // Global.ts, now the filename matters
    2. import { _decorator, Component, Node } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. @ccclass("Global")
    5. export class Global extends Component {
    6. public static backNode:any=null;
    7. public static backLabel:any=null;
    8. }
    1. // Back.ts
    2. import { _decorator, Component, Node, LabelComponent } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. // this feels more safe since you know where the object comes from
    5. import{Global}from "./Global";
    6. @ccclass("Back")
    7. export class Back extends Component {
    8. onLoad(){
    9. Global.backNode=this.node;
    10. Global.backLabel=this.getComponent(LabelComponent);
    11. }
    12. }
    1. // AnyScript.ts
    2. import { _decorator, Component, Node } from 'cc';
    3. const { ccclass, property } = _decorator;
    4. // this feels more safe since you know where the object comes from
    5. import{Global}from "./Global";
    6. @ccclass("AnyScript")
    7. export class AnyScript extends Component {
    8. start () {
    9. const text = "Back";
    10. Global.backLabel.string=text;
    11. }