From 740e604786b2c16a85188181ab4c5ad25720583d Mon Sep 17 00:00:00 2001 From: NicolasDemangeat Date: Thu, 1 Oct 2026 12:42:58 +0000 Subject: [PATCH] Automated Extension submission for issue #2284 --- extensions/community/DynamicCamera.json | 617 ++++++++++++++++++++++++ 1 file changed, 617 insertions(+) create mode 100644 extensions/community/DynamicCamera.json diff --git a/extensions/community/DynamicCamera.json b/extensions/community/DynamicCamera.json new file mode 100644 index 000000000..c2a4ad1bd --- /dev/null +++ b/extensions/community/DynamicCamera.json @@ -0,0 +1,617 @@ +{ + "author": "", + "category": "Camera", + "dimension": "", + "extensionNamespace": "", + "fullName": "Dynamic camera", + "gdevelopVersion": "", + "helpPath": "", + "iconUrl": "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48IURPQ1RZUEUgc3ZnIFBVQkxJQyAiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU4iICJodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9TVkcvMS4xL0RURC9zdmcxMS5kdGQiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0ibWRpLXZpZGVvLXN3aXRjaCIgd2lkdGg9IjI0IiBoZWlnaHQ9IjI0IiB2aWV3Qm94PSIwIDAgMjQgMjQiPjxwYXRoIGQ9Ik0xMywxNS41VjEzSDdWMTUuNUwzLjUsMTJMNyw4LjVWMTFIMTNWOC41TDE2LjUsMTJNMTgsOS41VjZBMSwxIDAgMCwwIDE3LDVIM0ExLDEgMCAwLDAgMiw2VjE4QTEsMSAwIDAsMCAzLDE5SDE3QTEsMSAwIDAsMCAxOCwxOFYxNC41TDIyLDE4LjVWNS41TDE4LDkuNVoiIC8+PC9zdmc+", + "name": "DynamicCamera", + "previewIconUrl": "https://asset-resources.gdevelop.io/public-resources/Icons/b5403e29f88bff30c33827253c726af24fb478f7b937892265b928709bad4ea1_video-switch.svg", + "shortDescription": "Automatically frames and smoothly zooms a camera to keep a group of objects in view.", + "version": "1.0.0", + "description": [ + "Keeps a camera centered and zoomed on a changing set of objects instead of a fixed view of the whole level.", + "Use cases:", + "- A construction or crafting game where the camera should follow the current build.", + "- A strategy game following a group of selected units.", + "- Any scene where the important area shrinks or grows over time." + ], + "tags": [ + "camera", + "zoom", + "framing", + "follow", + "bounding box" + ], + "authorIds": [ + "DBaDo3QWkIcsm9711Fe5Uit20CX2" + ], + "dependencies": [], + "globalVariables": [], + "sceneVariables": [ + { + "name": "DynamicCamera", + "persistentUuid": "83cce91e-7451-4b6f-90a6-61250fac2847", + "type": "structure", + "children": [ + { + "name": "BaseHeight", + "persistentUuid": "d4739e4c-367c-4c43-abf7-31d32b4b6d61", + "type": "number", + "value": 0 + }, + { + "name": "BaseWidth", + "persistentUuid": "9049aace-b440-48d2-8822-408d3904de8a", + "type": "number", + "value": 0 + }, + { + "name": "BoundsMaxX", + "persistentUuid": "4593ed1b-47bd-45bc-8e2c-ce2cb02508c4", + "type": "number", + "value": 0 + }, + { + "name": "BoundsMaxY", + "persistentUuid": "3f08b405-0eb3-459c-89b6-6a806a1aaf2b", + "type": "number", + "value": 0 + }, + { + "name": "BoundsMinX", + "persistentUuid": "9e1b39b1-959c-4f3d-9e9f-bef73cb8c0db", + "type": "number", + "value": 0 + }, + { + "name": "BoundsMinY", + "persistentUuid": "e055d7cc-dd78-4584-8bf9-b10da1bc33ca", + "type": "number", + "value": 0 + }, + { + "name": "CurrentX", + "persistentUuid": "3bddd1cd-ef64-40ce-b066-942480892986", + "type": "number", + "value": 0 + }, + { + "name": "CurrentY", + "persistentUuid": "bfa03498-e6f2-4d9c-a238-7187ba872885", + "type": "number", + "value": 0 + }, + { + "name": "CurrentZoom", + "persistentUuid": "e81afd02-4b79-423d-b8d0-c2012e2b6b4b", + "type": "number", + "value": 1 + }, + { + "name": "DesiredHeight", + "persistentUuid": "90894ab9-e05e-41e1-807e-4ebeaf27096a", + "type": "number", + "value": 0 + }, + { + "name": "DesiredWidth", + "persistentUuid": "36746771-7e67-44e3-b43c-9b0cde2e88d5", + "type": "number", + "value": 0 + }, + { + "name": "TargetX", + "persistentUuid": "00820bd3-277f-4b1e-b97f-c02770f0944b", + "type": "number", + "value": 0 + }, + { + "name": "TargetY", + "persistentUuid": "03aa467e-501a-4dac-b875-f5d7170c7236", + "type": "number", + "value": 0 + }, + { + "name": "TargetZoom", + "persistentUuid": "fb3cb7f6-5c05-4f33-aab8-4db56fd82ae6", + "type": "number", + "value": 0 + } + ] + } + ], + "eventsFunctions": [ + { + "description": "Move and zoom a camera so every instance of the given object or group stays inside the view, with padding, a minimum visible size, and smooth interpolation toward the target.", + "fullName": "Frame camera on objects", + "functionType": "Action", + "name": "FrameCameraOnObjects", + "sentence": "Frame camera on _PARAM1_ (layer: _PARAM2_, padding: _PARAM3_, min size: _PARAM4_, smoothing: _PARAM5_, zoom: _PARAM6_ to _PARAM7_)", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "NumberVariable" + }, + "parameters": [ + "DynamicCamera.CurrentZoom", + "=", + "0" + ] + }, + { + "type": { + "value": "BuiltinCommonInstructions::Once" + }, + "parameters": [] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.CurrentZoom", + "=", + "1" + ] + } + ] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Camera zone calculation", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMinX", + "=", + "999999" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMaxX", + "=", + "-999999" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMinY", + "=", + "999999" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMaxY", + "=", + "-999999" + ] + } + ], + "events": [ + { + "type": "BuiltinCommonInstructions::Comment", + "color": { + "b": 109, + "g": 230, + "r": 255, + "textB": 0, + "textG": 0, + "textR": 0 + }, + "comment": "Enclosing zone" + }, + { + "type": "BuiltinCommonInstructions::ForEach", + "object": "Objects", + "conditions": [], + "actions": [], + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Objects.CenterX() - Objects.Width()/2", + "<", + "DynamicCamera.BoundsMinX" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMinX", + "=", + "Objects.CenterX() - Objects.Width()/2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Objects.CenterX() + Objects.Width()/2", + ">", + "DynamicCamera.BoundsMaxX" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMaxX", + "=", + "Objects.CenterX() + Objects.Width()/2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Objects.CenterY() - Objects.Height()/2", + "<", + "DynamicCamera.BoundsMinY" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMinY", + "=", + "Objects.CenterY() - Objects.Height()/2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [ + { + "type": { + "value": "BuiltinCommonInstructions::CompareNumbers" + }, + "parameters": [ + "Objects.CenterY() + Objects.Height()/2", + ">", + "DynamicCamera.BoundsMaxY" + ] + } + ], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BoundsMaxY", + "=", + "Objects.CenterY() + Objects.Height()/2" + ] + } + ] + } + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Target", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.TargetX", + "=", + "(DynamicCamera.BoundsMinX + DynamicCamera.BoundsMaxX) / 2" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.TargetY", + "=", + "(DynamicCamera.BoundsMinY + DynamicCamera.BoundsMaxY) / 2" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.DesiredWidth", + "=", + "max((DynamicCamera.BoundsMaxX - DynamicCamera.BoundsMinX) + Padding * 2, MinVisibleSize)" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.DesiredHeight", + "=", + "max((DynamicCamera.BoundsMaxY - DynamicCamera.BoundsMinY) + Padding * 2, MinVisibleSize)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BaseWidth", + "=", + "CameraWidth(Layer) * DynamicCamera.CurrentZoom" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.BaseHeight", + "=", + "CameraHeight(Layer) * DynamicCamera.CurrentZoom" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.TargetZoom", + "=", + "min(DynamicCamera.BaseWidth / DynamicCamera.DesiredWidth, DynamicCamera.BaseHeight / DynamicCamera.DesiredHeight)" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.TargetZoom", + "=", + "min(max(DynamicCamera.TargetZoom, MinZoom), MaxZoom)" + ] + } + ] + } + ], + "parameters": [] + }, + { + "colorB": 228, + "colorG": 176, + "colorR": 74, + "creationTime": 0, + "name": "Smoothing and application", + "source": "", + "type": "BuiltinCommonInstructions::Group", + "events": [ + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.CurrentX", + "+", + "(DynamicCamera.TargetX - DynamicCamera.CurrentX) * Smoothing * TimeDelta()" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.CurrentY", + "+", + "(DynamicCamera.TargetY - DynamicCamera.CurrentY) * Smoothing * TimeDelta()" + ] + }, + { + "type": { + "value": "SetNumberVariable" + }, + "parameters": [ + "DynamicCamera.CurrentZoom", + "+", + "(DynamicCamera.TargetZoom - DynamicCamera.CurrentZoom) * Smoothing * TimeDelta()" + ] + } + ] + }, + { + "type": "BuiltinCommonInstructions::Standard", + "conditions": [], + "actions": [ + { + "type": { + "value": "ZoomCamera" + }, + "parameters": [ + "", + "DynamicCamera.CurrentZoom", + "Layer", + "" + ] + }, + { + "type": { + "value": "SetCameraCenterX" + }, + "parameters": [ + "", + "=", + "DynamicCamera.CurrentX", + "Layer", + "" + ] + }, + { + "type": { + "value": "SetCameraCenterY" + }, + "parameters": [ + "", + "=", + "DynamicCamera.CurrentY", + "Layer", + "" + ] + } + ] + } + ], + "parameters": [] + } + ], + "parameters": [ + { + "description": "The object or group to keep visible on screen", + "name": "Objects", + "type": "objectList" + }, + { + "description": "The layer whose camera should be moved", + "name": "Layer", + "type": "string" + }, + { + "description": "Extra space, in pixels, kept around the objects", + "name": "Padding", + "type": "expression" + }, + { + "description": "Minimum width/height the camera will show, even if the objects are very close together", + "name": "MinVisibleSize", + "type": "expression" + }, + { + "description": "How fast the camera catches up to its target. Higher is snappier", + "name": "Smoothing", + "type": "expression" + }, + { + "description": "The camera will never zoom out past this value", + "name": "MinZoom", + "type": "expression" + }, + { + "description": "The camera will never zoom in past this value", + "name": "MaxZoom", + "type": "expression" + } + ], + "objectGroups": [] + } + ], + "eventsFunctionsFolderStructure": { + "folderName": "__ROOT", + "children": [ + { + "functionName": "FrameCameraOnObjects" + } + ] + }, + "eventsBasedBehaviors": [], + "eventsBasedObjects": [] +}