Unique Conditions for Each Clone and Instance

Hello everyone,

In the PG below, grey boxes move around looking for “food,” which are the yellow boxes.

https://www.babylonjs-playground.com/#UPRU8R

I’ve been able to create certain game mechanics for individual meshes, but I’m not sure how to apply these to the clones (grey boxes) and instances (yellow boxes).

  1. Each grey box starts with 100 health, and loses it steadily over time (example 10 seconds).

  2. When a grey box and a yellow box collide, that grey box’s health resets to 100, and the yellow food box disappears.

  3. If a grey box does not collide with a yellow box within 10 seconds, the grey box disappears.

Again, I’m not having trouble creating these mechanics for individual meshes (i.e. “box” and “food”), but rather for all the other clones and instances (i.e. “box24” and “food116”).

Any help or suggestions would be greatly appreciated :smiley: :+1:

why not storing the info in mesh.metadata ? it is a free bag you can use for any of your custom needs ???

So each mesh/instance could store its health and time until die and it would then be easy to iterate through them ?

Hello @sebavan,

I have no idea what mesh.metadata is, but it sounds like a great solution! Hopefully I can find documentation or examples of how to implement this.

However, even if I can get each instance or clone to store metadata, I still can’t figure out how to get hundreds of different meshes all with unique names to recognize each other (i.e. an intersection).

For instance, in the code below, when I reference ALL of the 200 food instances from the foodArray (foodArray[i]), the scene crashes :thinking: However, this code works if I check for an intersection with just a single instance (replace foodArray[i] with just “food”).

scene.registerBeforeRender(function () {

    for (var i = 0; i < 200; i++) {

    if (cloneArray[i].intersectsMesh(foodArray[i], false)) {
        cloneArray[i].material.diffuseColor = new BABYLON.Color3(1, 0, 0);
    }else{
        cloneArray[i].material.diffuseColor = new BABYLON.Color3(0, 1, 0);
    }

    }
});

metadata is just a json object you can use as you want completely untyped.

About your issue maybe @Cedric or @RaananW have a proposal ???

Thanks again for the help @sebavan!

I’m still unable to solve this problem unfortunately, so I’m going to try and simplify the question below for anyone who might know the solution.

How can two objects from different arrays detect an intersection when their specific ID is not known by the user? Example: “box12” and “food143” (named when created: (“box” + index), and (“food” + index)).

Have you ever thought about the Solid Particle System https://doc.babylonjs.com/How_To/Solid_Particles

There are snippets looking at multiple collisions with SPS Babylon.js Documentation

Without a playground I cannot work out why it crashes but with the code you show

registerBeforeRender(function () {

Copy to clipboard


    for (var i = 0; i < 200; i++) {

    if (cloneArray[i].intersectsMesh(foodArray[i], false)) {
        cloneArray[i].material.diffuseColor = new BABYLON.Color3(1, 0, 0);
    }else{
        cloneArray[i].material.diffuseColor = new BABYLON.Color3(0, 1, 0);
    }

    }
});

each cloneArray will only be checked against the one entry in the foodArray, the one with the same index. For any in the cloneArray to be checked against any in the foodArray you need two loops with i and j and check

clineArray[i] against foodArray[j]

Hello @JohnK! Thanks for taking a look at this!

I was actually able to get things working with the code below. I will definitely investigate the SPS, as it might be a better option for my project in the long run. Does the SPS offer any advantages over using instances? I’ve only been programming for a month, so I’m not sure if what I wrote below is the best solution, but it works! :thinking:

    for (var i = 0; i < cloneArray.length; i++) {

    cloneArray[i].actionManager = new BABYLON.ActionManager(scene);
    foodArray.forEach((food) => {
        
        
        cloneArray[i].actionManager.registerAction(
    new BABYLON.ExecuteCodeAction(
        {
        trigger:BABYLON.ActionManager.OnIntersectionEnterTrigger,
        parameter:food
        }, 
        function(){
            food.dispose();
        }
    )
);
        
        });
      }

Hello again @JohnK,

I just realized that there actually is one element of the code above that is not 100%. I’m unable to get both the “food” and the cloneArray[i] mesh to disappear.

I’ve tried the following:

 function(){
        food.dispose();
        cloneArray[i].dispose();
    }

If it’s not obvious and a PG is needed, just let me know.

Thanks again!

Here’s the PG :smiley: :+1:
https://www.babylonjs-playground.com/#2CHIX4

Interesting project so played around a bit. Here’s my version of food removal https://www.babylonjs-playground.com/#2CHIX4#1

Also added predator removal using a metadata and a set time https://www.babylonjs-playground.com/#2CHIX4#2 see lines 73, 74 and 167 to 171 and 183

lines 73, 74 could just have been cloneB.lifeTimeRemaining = 60 * 1000; I believe the advantage of using metadata is that Babylon.js picks the metadata property up when the mesh is exported and serializes it.

2 Likes

Thanks for the updates to the code! Someone else also mentioned that metadata would be useful for this project, but I couldn’t at the time find any examples, so it’s really helpful that you added it. When I researched it, it seemed like metadata was something that got imported along with a mesh, or was contained in a separate file. It seems like metadata will help me accomplish the most important part of this project, which is to have randomly-generated creatures with various traits that can change over time.

When the creatures (grey boxes for now) move around, they will continuously lose energy. It looks like you set this up with lifeTimeRemaining (60 seconds). This is perfect because I had no idea how to accomplish this. Now, I’ll see if I can reset that 60-second clock for each individual creature when it intersects with a food item.

The most challenging part of this project (I think :thinking:), will be the digital DNA element involving the inheritance of metadata. I don’t even know if this will be possible, but I hope so!

For instance:

Creature 1: metadata trait A = 1, metadata trait B = 2

Creature 2: metadata trait A = 3, metadata trait B = 4

When they intersect (reproduce) “offspring” with random trait values:

Offspring creature: metadata trait A = (1 or 3), metadata trait B = (2 or 4)

Thank you again @JohnK for the help and suggestions! :smiley: :+1:

1 Like

This should be straightforward to do on intersection.
It could be interesting to vary the life time for each predator and for each food item to be of varying size and add an amount of life when eaten proportional to its size.

I actually made some progress with that today:
https://www.babylonjs-playground.com/#2CHIX4#3

I randomized their speed and made that inversely proportional to their lifespan.

There are two issues now:

  1. I can only use one action manager for the clones. One removes the food, the other scales the y axis, but only one at a time works (whichever is read last by the scene).

  2. I have absolutely no idea how to combine metadata randomly when two clones intersect to create a new clone “offspring.” :thinking:

Forgot to add that having the food provide different amounts of energy is a great idea :smiley: :+1: