Layer in Javascript

Before proceeding, please use the forum search feature at the top of the page to check if your question has already been answered.

How do I…

I can create objects in javascript and assigned them to existing layers.
It works.

But I’m unable so far to create a layer in javascript and assigned objects to it.
The layers are created, objects are created and assigned to it, but they do not show up on the screen.

If I assigned the objects to layers defined from the GUI, it does work.
So, it’s not an object problem.

What is the expected result

I expect the object to appear on the screen for this new layer created in JS.

What is the actual result

Objects and Layers show up in the debugger, but not on the screen.

Related screenshots

Code below.

runtimeScene.setBackgroundColor(100,100,240);
//
// One Cube, one layer, on/off
//
console.log("Once Cube script started...");
const scene = runtimeScene;
const startX = 200;
const startY = 200;
const startZ = 0;
console.log("Building pyramid layers...");

// FIXED: Access camera through the default layer
const baseLayer = scene.getLayer("");
if (!baseLayer) {
    console.error("CRITICAL: Base layer not found. Cannot build pyramid.");
    return;
}
console.log("Base layer found. Proceeding to build layers.");

// const layerName = `Floor_1`;
const layerName = `Layer3`;
// Check if the layer already exists to avoid re-creating it.
if (!scene.hasLayer(layerName)) {
    console.log(`Layer '${layerName}' does not exist. Creating it...`);
    // Create new layer with proper structure
    const layerData = {
        name: layerName,
        visibility: true,
        effects: [],
        cameras: [],
        ambientLightColorR: 200,
        ambientLightColorG: 200,
        ambientLightColorB: 200,
        isLightingLayer: false,
        followBaseLayerCamera: true
    };
    scene.addLayer(layerData);
    console.log(`Layer '${layerName}' created.`);
}

// FIXED: Proper object creation in GDevelop
try {
    // Method 1: Direct object creation (most common)
    const newCube = scene.createObject("Cube");
    
    if (!newCube) {
        console.error("Failed to create cube object. Make sure 'Cube' object exists in your scene.");
        return;
    }
    
    console.log("Cube object created successfully");
    
    // Set the layer
    newCube.setLayer(layerName);
    
    // Set position immediately after creation
    const posX = startX;
    const posY = startY;
    const posZ = startZ;
    
    newCube.setPosition(posX, posY);
    newCube.setZOrder(1)
    
    // Try different Z-setting methods
    if (typeof newCube.setZ === 'function') {
        newCube.setZ(posZ);
    } else if (typeof newCube.setZOrder === 'function') {
        newCube.setZOrder(posZ);
    }
    
    // Set color/tint
    const r = Math.min(255, 50);
    const g = Math.min(255, 90);
    const b = Math.min(255, 120);
    
    // Try different color methods
    if (typeof newCube.setColor === 'function') {
        newCube.setColor(`${r};${g};${b}`);
    } else if (typeof newCube.setTint === 'function') {
        newCube.setTint(`${r};${g};${b}`);
    } else if (typeof newCube.setColorTransform === 'function') {
        newCube.setColorTransform(r/255, g/255, b/255, 1);
    }
    
    // Make sure object is visible and active
    if (typeof newCube.hide === 'function') {
        newCube.hide(false);
    }
    if (typeof newCube.activateBehavior === 'function') {
        newCube.activateBehavior("", true);
    }
    
    console.log(`Created cube at position (${posX}, ${posY}, ${posZ})`);
    
} catch (error) {
    console.error("Error creating cube:", error);
}

// FIXED: Debugging info with correct API calls
console.log("=== DEBUGGING INFO ===");
try {
    // Get all objects in the scene
   
   // Replace 'MyObject' with your actual object name
    const allObjects = runtimeScene.getObjects("Cube");
    console.log("Total objects named Cube:", allObjects.length);

    
    // List all objects and their positions
    for (let i = 0; i < allObjects.length; i++) {
        const obj = allObjects[i];
        console.log(`Object ${i}: ${obj.getName()} at (${obj.getX()}, ${obj.getY()})`);
    }
    
    // Alternative way to check for specific object types
    const cubeObjects = scene.getObjects("Cube");
    console.log("Cube objects found:", cubeObjects.length);
    
} catch (debugError) {
    console.error("Error in debugging section:", debugError);
}

console.log("Pyramid generation complete.");
console.log("This runs only once");

Project files (optional)

N/A

Layers in Debugger:

Cube 01:

Cube 02:

Cube 03:

Cube 01 and 02 were created with the GUI.
Cube 03 created with the javascript.

Layer2 was created via the GUI.
Floor_1 (Layer) was created via javascript.

I can’t see why object assigned to layer “Floor_1” are not being displayed in the game.

Why do you want to create layers dynamically?

Why building the layer dynamically?

1: To learn the gdjs class :slight_smile:

2: For this project

I build a pyramid from cube and want to be able to hide/show layer by layer.
The height (number of Layer) is variable.

Technically for this project, I could just pre-defined each layer (from 1 to 10 for example).

Or set an instance variable (Level or Group ) to represent this layer, and use it to hide/show objects based on this variable.

I initially thought about using the Object Group, but can’t find any function to do that yet.

===

In the debugger, the layers data created via the GUI or the JS looks the same.

So to summarize the issue, objects created and assigned to a layer (created in JS), do not show up in the scene.

Not critical for my small project, as I can find workaround, but looks like a bug.

When I get some time, I will create a big report with a simple project.