[DOWNLOAD] New Save States + Save / Load All Variable + Object Culling Script v5.0 - Project File! A Cluster of Awesome and Helptful Tools!

Here’s the code to apply to several layers, it’s been tested!

runtimeScene.setBackgroundColor(100,100,240);
// Liste des calques à traiter pour le culling
const layersToCull = ["", "layer1", "layer2"]; // Ajouter ici les noms des calques sur lesquels appliquer le culling

// Initialiser l'objet deletedObjects pour chaque calque si nécessaire
if (!runtimeScene.deletedObjects) {
    runtimeScene.deletedObjects = {};
}

// Obtenir la valeur de la variable CullBuffer une seule fois
const cullBuffer = runtimeScene.getVariables().get("CullBuffer").getAsNumber();

// Processus de culling pour chaque calque
layersToCull.forEach(layerName => {
    // Initialiser deletedObjects pour le calque courant
    if (!runtimeScene.deletedObjects[layerName]) {
        runtimeScene.deletedObjects[layerName] = {};
    }

    // Obtenir la position de la caméra et la taille du calque actuel
    const cameraLayer = runtimeScene.getLayer(layerName);
    const cameraX = cameraLayer.getCameraX();
    const cameraY = cameraLayer.getCameraY();
    const cameraWidth = cameraLayer.getCameraWidth();
    const cameraHeight = cameraLayer.getCameraHeight();

    // Calculer les limites de culling basées sur CullBuffer
    const leftBoundary = cameraX - cameraWidth / 2 - cullBuffer;
    const rightBoundary = cameraX + cameraWidth / 2 + cullBuffer;
    const topBoundary = cameraY - cameraHeight / 2 - cullBuffer;
    const bottomBoundary = cameraY + cameraHeight / 2 + cullBuffer;

    // Récupérer tous les objets de la scène
    const allObjectsInstances = runtimeScene.getAdhocListOfAllInstances();

    // Créer des tableaux pour stocker les objets à supprimer et recréer
    const objectsToDelete = [];
    const objectsToStoreAndDelete = [];

    // Limiter le nombre d'objets traités par frame pour éviter les pics d'usage CPU
    const maxObjectsPerFrame = 50; // Ajustez cette valeur pour optimiser les performances
    const startIndex = runtimeScene.getVariables().has("CullStartIndex_" + layerName)
        ? runtimeScene.getVariables().get("CullStartIndex_" + layerName).getAsNumber()
        : 0;
    const endIndex = Math.min(startIndex + maxObjectsPerFrame, allObjectsInstances.length);

    runtimeScene.getVariables().get("CullStartIndex_" + layerName).setNumber(endIndex === allObjectsInstances.length ? 0 : endIndex);

    // Obtenir le temps actuel de la scène pour les objets restaurés
    const currentTime = runtimeScene.getTimeManager().getTimeFromStart() / 1000;

    // Parcourir les objets du sous-ensemble sélectionné
    for (let i = startIndex; i < endIndex; i++) {
        const object = allObjectsInstances[i];
        const objectName = object.getName();
        const objectLayer = object.getLayer();

        // Ne traiter que les objets du calque en cours
        if (objectLayer !== layerName) continue;

        const variables = object.getVariables();

        // Vérifier si l'objet a une variable "ExcludeCull" définie à true
        if (variables.has("ExcludeCull") && variables.get("ExcludeCull").getAsBoolean()) {
            continue; // Exclure cet objet du culling
        }

        // Obtenir la boîte englobante de l'objet
        const aabb = object.getAABB();
        const objectLeft = aabb.min[0];
        const objectRight = aabb.max[0];
        const objectTop = aabb.min[1];
        const objectBottom = aabb.max[1];

        // Vérifier si l'objet est en dehors des limites du culling
        if (objectRight < leftBoundary || objectLeft > rightBoundary || objectBottom < topBoundary || objectTop > bottomBoundary) {
            // Vérifier si l'objet a une variable "Cull" définie à true
            if (variables.has("Cull") && variables.get("Cull").getAsBoolean()) {
                objectsToDelete.push(object); // Ajouter l'objet pour suppression immédiate
            } else {
                // Stocker les propriétés de l'objet pour recréation future
                if (!runtimeScene.deletedObjects[layerName][objectName]) {
                    runtimeScene.deletedObjects[layerName][objectName] = [];
                }

                const objectProperties = {
                    x: object.getX(),
                    y: object.getY(),
                    zOrder: object.getZOrder(),
                    angle: object.getAngle(),
                    layer: objectLayer,
                    hidden: object.isHidden(),
                    variables: {},
                    timers: {},
                    cullTime: currentTime
                };

                // Enregistrer les variables de l'objet
                const objectVariablesList = variables._variables.items;
                for (const variableName in objectVariablesList) {
                    if (objectVariablesList.hasOwnProperty(variableName)) {
                        objectProperties.variables[variableName] = objectVariablesList[variableName].getAsString();
                    }
                }

                // Enregistrer les propriétés optionnelles
                if (object.getWidth) objectProperties.width = object.getWidth();
                if (object.getHeight) objectProperties.height = object.getHeight();
                if (object.getOpacity) objectProperties.opacity = object.getOpacity();

                // Enregistrer les timers de l'objet
                if (object._timers && object._timers.items) {
                    const timerItems = object._timers.items;
                    for (const timerName in timerItems) {
                        if (timerItems.hasOwnProperty(timerName)) {
                            objectProperties.timers[timerName] = timerItems[timerName].getTime() / 1000.0;
                        }
                    }
                }

                runtimeScene.deletedObjects[layerName][objectName].push(objectProperties);
                objectsToStoreAndDelete.push(object);
            }
        }
    }

    // Supprimer les objets complètement hors champ
    objectsToDelete.forEach(obj => obj.deleteFromScene(runtimeScene));
    objectsToStoreAndDelete.forEach(obj => obj.deleteFromScene(runtimeScene));

    // Récupérer le temps actuel de la scène pour restaurer les objets
    const restoreTime = runtimeScene.getTimeManager().getTimeFromStart() / 1000;

    // Recréer les objets dans les limites
    const deletedObjects = runtimeScene.deletedObjects[layerName];
    for (let objectName in deletedObjects) {
        const objectList = deletedObjects[objectName];
        for (let i = objectList.length - 1; i >= 0; i--) {
            const data = objectList[i];
            const objectLeft = data.x;
            const objectRight = data.x + (data.width || 0);
            const objectTop = data.y;
            const objectBottom = data.y + (data.height || 0);

            // Vérifier si la position est dans les limites de recréation
            if (objectRight >= leftBoundary && objectLeft <= rightBoundary && objectBottom >= topBoundary && objectTop <= bottomBoundary) {
                const elapsedTime = restoreTime - data.cullTime;

                // Recréer l'objet
                const newObject = runtimeScene.createObject(objectName);
                newObject.setPosition(data.x, data.y);
                newObject.setZOrder(data.zOrder);
                newObject.setAngle(data.angle);
                newObject.setLayer(data.layer);

                if (data.width !== undefined && newObject.setWidth) newObject.setWidth(data.width);
                if (data.height !== undefined && newObject.setHeight) newObject.setHeight(data.height);
                if (data.opacity !== undefined && newObject.setOpacity) newObject.setOpacity(data.opacity);

                if (data.hidden !== undefined) newObject.hide(data.hidden);

                const targetVariables = newObject.getVariables();
                const sourceVariables = data.variables;
                for (const variableName in sourceVariables) {
                    if (sourceVariables.hasOwnProperty(variableName)) {
                        targetVariables.get(variableName).setString(sourceVariables[variableName]);
                    }
                }

                const objectTimers = data.timers;
                for (const timerName in objectTimers) {
                    const timerValue = objectTimers[timerName];
                    newObject.resetTimer(timerName);
                    newObject._timers.get(timerName).setTime((timerValue + elapsedTime) * 1000);
                }

                objectList.splice(i, 1);
            }
        }
    }

    for (let objectName in deletedObjects) {
        if (deletedObjects[objectName].length === 0) {
            delete deletedObjects[objectName];
        }
    }
});

4 Likes