Is there a way to create a new node using code/script?

Hi,

I am making a game where obstacles are generated in random places in my scene. I have created an obstacle node with a collider component attached to it and wrote a script that selects a random place on the screen and adds a prefab child to the obstacle node. Everything works fine, every time a new prefab is created the node’s position gets updated and the collider is updated to the new position as well.

BUT

I can only have one obstacle at a time. Every time a new prefab is created, the previous one gets destroyed (or moved to the new location). Does anyone know how I can get the code/script to create new prefabs without the previous ones getting destroyed or removed? Should my script be creating new nodes with colliders in them so there can be more than one displayed at a time?

For reference it’s like the Quick Start game Making Stars section and I want to have more than one star at a time.

Any help is appreciated, let me know if you need more info.
Thanks!

please share your codes.

I haven’t had problems with many simultaneous instances of the same prefab, maybe you should manage the prefabs in an array and use some kind of iterator to destroy the one that needs destroying, since it sounds a bit like you’re overwriting the previous instance instead of creating a new one, hence the dissappearing.

Sorry in case this turns out to be completely beside the point and useless.

cheers

@ozergul @fliegenfuerst
Here is my code to add a random obstacle (4 obstacles in total):

properties: {
        smallRockPrefab: {
            default: null,
            type: cc.Prefab
        },
        smallRockNode: {
            default: null,
            type: cc.Node
        },
        bigRockPrefab: {
            default: null,
            type: cc.Prefab
        },
        bigRockNode: {
            default: null,
            type: cc.Node
        },
        bombPrefab: {
            default: null,
            type: cc.Prefab
        },
        bombNode: {
            default: null,
            type: cc.Node
        },
        rocketPrefab: {
            default: null,
            type: cc.Prefab
        },
        rocketNode: {
            default: null,
            type: cc.Node
        }
}

// Select a random obstacle (1 to 4 obstacles)
var obstacleNumber = Math.floor((Math.random() * 4) + 1);
var newObstacle;

switch (obstacleNumber) {
        case 1:
            newObstacle = cc.instantiate(this.smallRockPrefab);
            this.smallRockNode.addChild(newObstacle);
            break;
        case 2:
            newObstacle = cc.instantiate(this.bigRockPrefab);
            this.bigRockNode.addChild(newObstacle);
            break;
        case 3:
            newObstacle = cc.instantiate(this.bombPrefab);
            this.bombNode.addChild(newObstacle);
            break;
        case 4:
            newObstacle = cc.instantiate(this.rocketPrefab);
            this.rocketNode.addChild(newObstacle);
            break;
        }

just a feeling since i’m not too on spot about variable scopes, but does it change anything if you
a: set var newObstacle=null instead of just declaring the variable
b: write var newObstacle = cc.instantiate(this.prefab); in each of the cases instead of declaring it before?

that might actually do absolutely nothing but in javascript i’ve made a habit of first trying out code placement changes before grinding my gears too much.

apart from this ‘instinctive’ approach, I’d have to request more code, if it’s like the star-game example I suppose the destruction of a prefab is handled inside the prefabs code component? maybe something goes wrong there? I don’t suppose so though.

cheers

1 Like

how do you call this script? or who do your game use it?

@ozergul @eydamson
Here is more code and info:

Nodes:

The obstacles property (has obstacles script attached to it):

Each obstacle’s property is like this and has a different BoxCollider Tag:

Here is the function in the obstacles script that generates one of the obstacles in a random location

// This makes a new obstacle in the scene, it is called at random times
generateNewObstacle: function () {
    // Select a random obstacle (1 to 4 obstacles)
    var obstacleNumber = Math.floor((Math.random() * 4) + 1);
    var newObstacle, obstacleHeight;

    switch (obstacleNumber) {
    case this.spriteTag.smallRock:
        newObstacle = cc.instantiate(this.smallRockPrefab);
        break;
    case this.spriteTag.bigRock:
        newObstacle = cc.instantiate(this.bigRockPrefab);
        break;
    case this.spriteTag.bomb:
        newObstacle = cc.instantiate(this.bombPrefab);
        break;
    case this.spriteTag.rocket:
        newObstacle = cc.instantiate(this.rocketPrefab);
        break;
    }
    
    // Select a random height
    var randomHeight = cc.randomMinus1To1();
    // if randomHeight is less than 0 then place obstacle in bottom half of road
    if (randomHeight < 0)
        obstacleHeight = (Math.abs(randomHeight) * this.sidelineBottom.getPositionY()) + (obstacleSize.height / 2);
    // else place obstacle in top half of road
    else
        obstacleHeight = (Math.abs(randomHeight) * this.sidelineTop.getPositionY()) - (obstacleSize.height / 2);

    // Set obstacle's position and move action
    var newObstacleAction = new cc.MoveBy(this.roadSpeed, cc.p(-this.roadLinesWidth, 0));
    var newObstaclePosition = cc.p((cc.winSize.width / 2) + (obstacleSize.width / 2)-40, obstacleHeight);

    // Add this obstacle prefab to the obstacles Node
    switch (obstacleNumber) {
    case this.spriteTag.smallRock:
        // smallRock
        this.smallRockNode.addChild(newObstacle);
        this.smallRockNode.setPosition(newObstaclePosition);
        break;
    case this.spriteTag.bigRock:
        // bigRock
        this.bigRockNode.addChild(newObstacle);
        this.bigRockNode.setPosition(newObstaclePosition);
        break;
    case this.spriteTag.bomb:
        // bomb
        this.bombNode.addChild(newObstacle);
        this.bombNode.setPosition(newObstaclePosition);
        break;
    case this.spriteTag.rocket:
        // rocket
        this.rocketNode.addChild(newObstacle);
        this.rocketNode.setPosition(newObstaclePosition);
        break;
    }
},

@fliegenfuerst thanks for those suggestions but ya they did nothing.

Cheers.

hi,
why do you use addChild method to store instantiated prefabs?

BUT
I can only have one obstacle at a time. Every time a new prefab is created, the previous one gets destroyed (or moved to the new location). Does anyone know how I can get the code/script to create new prefabs without the previous ones getting destroyed or removed? Should my script be creating new nodes with colliders in them so there can be more than one displayed at a time?

because of this lines:

this.bigRockNode.setPosition(newObstaclePosition);

position of bigRockNode, bombnode or other two is changing because you set the position of parent node to child node’s position every time.

instantiated prefabs are over and over. you can see it by this codes:

console.log(this.bigRockNode)

have a look at child nodes.

What method should I use if it’s not addChild?

I used to only set position of the child (prefab) but then the boxCollider would not update to the new position of the child prefab. Also, how would I create more than one instance of the bigRockNode BoxCollider for each prefab?

Thanks.

(I did not try instance object with collider component)

you can use:

var newObject = cc.instantiate(this.prefab)
newObject.parent = parentNode