Iv finished working on the new version on the Culling Script!
It still works about the same, the difference being i added a suit of awesome events and Scripts to compliment it!
Link down bellow, 100% Free, you can simply Download, open the project and Copy / Paste into your own project!
It will work with nothing else needed to be done.
But heres some basic instructions…
This is what youll find in the Project:
Whats included:
-
An Easy and Simple way of having “Save States”, with a push of a Button, the game will Save, then if you want to Load simply press another button and the game will Reload.
-
When the game Saves and Reloads, it will also Save and Load all of your Variables, Global, Scene and Objects.
-
…and you also get the fine tunned Version of my Object Culling Script.
So how do i use this thing?
Simply Copy and Paste the whole thing into your Project, put it at the Bottom of your event sheet for better results.
The save state Keys by Default are:
- Numpad1 to Save
- Numpad9 to Load
- Numpad7 to Delete Save
You can change these keys by simply opening the Event groups and changing them…
Just make sure 03 - Save Objects and 04 - Save Variables have the exact same Key to trigger the events… or the same condition is you customize it.
You can Adjust the Culling Buffer in the 02 - Cull Script Options > Cull Buffer Size
To Exclude Culling or Permanently Cull Objects, make two Object Groups:
- ExcludeObjects for objects you dont want to be culled
- StayCulled for objects you want to stay deleted
DISCLAIMER This whole thing only works on the Base Layer for now.
Itch Download Link
Check out the YouTube Channel if you like stuff like this!
7 Likes
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];
}
}
});
3 Likes