#Cannot replicate example from Documentation

1 messages · Page 1 of 1 (latest)

narrow tangle
#

I am trying to modify a little bit Spawn Objects Over Time from here: https://engine.needle.tools/docs/scripting-examples.html#spawn-objects-over-time
Firstly it demanded to use asset reference, because serializable didnt work well, now it says "instance.clone() is not a function" i tride to use Object3D but error was the same
My code looks like this:
import { AssetReference, Behaviour, GameObject, LogType, serializeable, showBalloonMessage, WaitForSeconds } from "@needle-tools/engine";
import { Event, Object3D, Vector3 } from "three";

export class TimedSpawn extends Behaviour {

@serializeable(AssetReference)
object!: GameObject;

interval: number = 1000;
max: number = 100;
spawnRange: Vector3 = new Vector3(10, 10, 10);  // Default range is (-10 to 10) for x, y, z

private spawned: number = 0;


awake() {
    if (!this.object) {
        console.warn("TimedSpawn: no object to spawn");
        showBalloonMessage("TimedSpawn: no object to spawn", LogType.Warn);
        return;
    }
    GameObject.setActive(this.object, false);
    this.startCoroutine(this.spawn())
}

*spawn() {
    if (!this.object) return;
    while (this.spawned < this.max) {
        const instance = GameObject.instantiate(this.object); 
        const randomPos = this.getRandomPosition();
        instance!.transform.position.x = randomPos.x;
        instance!.transform.position.y = randomPos.y;
        instance!.transform.position.z = randomPos.z;
        GameObject.setActive(instance!, true);
        this.spawned += 1;
        yield WaitForSeconds(this.interval / 1000);
    }
}

getRandomPosition(): Vector3 {
    const randomX = Math.random() * this.spawnRange.x * 2 - this.spawnRange.x;
    const randomY = Math.random() * this.spawnRange.y * 2 - this.spawnRange.y;
    const randomZ = Math.random() * this.spawnRange.z * 2 - this.spawnRange.z;

    return new Vector3(randomX, randomY, randomZ);
}

}

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally. Needle Exporter for Unity bridges the Unity Editor and the web runtime. It helps you to export your assets, animations, lightmaps and so on to the web. It is...

#

@mild pawn I tried just to copy paste the code first to check, but it showed error that serializable used improperly, i just dont get it

drowsy briar
#

Hey 👋 please don't ping the members directly, we see your message and will reply in a reasonable time :)

mild pawn
#

Hi, it looks like you mix up types:

@serializeable(AssetReference)
object!: GameObject;

^ this doesnt make sense. It is either both AssetRefernce or both GameObject.

What you probably want is:

@serializeable(AssetReference)
object!: AssetReference;

Also: please format your posted code using ` + ts (see my screenshot)

#

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally. Needle Exporter for Unity bridges the Unity Editor and the web runtime. It helps you to export your assets, animations, lightmaps and so on to the web. It is...

narrow tangle
#

Ok, but when I inser both AssetReference, I got this:

#

Ahhhhh

#

Sorry

#

I am stupit

#

Thank you so much

#

I figured it out

mild pawn
#

Right, you need to share a bit more information about your project for being able to advice ah good to hear 😉

narrow tangle
mild pawn
#

you can also always download the sample projects https://engine.needle.tools/samples and look at one of the scenes that has a feature similar to what you want - the code is completely available

#

no worries

#

Feel free to ask whenn you're stuck or share what you're working on. Just don't ping as kipash said 🙂

narrow tangle
#

But I want to say that your engine is awesome, so much possibilities

narrow tangle
#

This one works, but only for one time, and it ignores current position of the spawner, I tried everything, including chatGPT, but cannot find where I am wrong. I just need spawn object periodically in certain location, with some random coordinate drift

import { Vector3 } from "three";

export class TimedSpawn extends Behaviour {
    
    @serializeable(AssetReference)
    object!: AssetReference;

    interval: number = 1000;
    max: number = 100;
    spawnRange: Vector3 = new Vector3(10, 10, 10);  // Default range is (-10 to 10) for x, y, z

    private spawned: number = 0;
    

    awake() {
        if (!this.object) {
            console.warn("TimedSpawn: no object to spawn");
            showBalloonMessage("TimedSpawn: no object to spawn", LogType.Warn);
            return;
        }
        
        // Start the spawn coroutine
        this.startCoroutine(this.spawn());
    }

    *spawn() {
        while (this.spawned < this.max) {
            // Use yield to handle the promise
            const instance = yield this.object!.instantiate();
            if (!instance) return;

            const spawnerPos = this.gameObject.transform.position;  // Get the spawner's current position
            const randomPos = this.getRandomPosition();

            // Adjust the spawned object's position by adding the spawner's position to the random offset
            instance.transform.position.x = spawnerPos.x + randomPos.x;
            instance.transform.position.y = spawnerPos.y + randomPos.y;
            instance.transform.position.z = spawnerPos.z + randomPos.z;

            GameObject.setActive(instance, true);
            this.spawned += 1;
            yield WaitForSeconds(this.interval / 1000);
        }
    }

    getRandomPosition(): Vector3 {
        const randomX = Math.random() * this.spawnRange.x * 2 - this.spawnRange.x;
        const randomY = Math.random() * this.spawnRange.y * 2 - this.spawnRange.y;
        const randomZ = Math.random() * this.spawnRange.z * 2 - this.spawnRange.z;

        return new Vector3(randomX, randomY, randomZ);
    }
}```
mild pawn
#
  • Instead of yield make sure to await the "instantiate" call (it's async)
  • Note that position is local position in threejs and not world position as in Unity (see docs) - we have utility methods for getWorldPosition and setWorldPosition that you can use instead
#

I would refactor the method to run async

onEnable() { this.spawn() }

async spawn() {
  while(this.enabled && this.spawned < this.max) 
  {
    await delay(2000); // util method from needle engine
    // your other spawn code....
  }  
}
narrow tangle
#

I completely forgot to say thank you!

#

Thank you very much!