diff --git a/GDJS/Runtime/InGameEditor/InGameEditor.tsx b/GDJS/Runtime/InGameEditor/InGameEditor.tsx index 9db1d49fce00..31ef726773b7 100644 --- a/GDJS/Runtime/InGameEditor/InGameEditor.tsx +++ b/GDJS/Runtime/InGameEditor/InGameEditor.tsx @@ -3347,6 +3347,15 @@ namespace gdjs { return !!instanceData && !!instanceData.sealed; } + /** + * Instances hidden at start stay visible in the editor, but extensions + * can use this to disable what can't be shown as "hidden" (like lights). + */ + isInstanceHiddenAtStart(object: gdjs.RuntimeObject): boolean { + const instanceData = this._getInstanceData(object.persistentUuid); + return !!instanceData && !!instanceData.hidden; + } + private _addInstances(addedInstances: Array) { for (const addedInstance of addedInstances) { this._editedInstanceDataList.push(addedInstance); @@ -3804,6 +3813,7 @@ namespace gdjs { ); } runtimeObject.extraInitializationFromInitialInstance(instance); + gdjs.RuntimeObject.applyInGameEditorMinimumOpacity(runtimeObject); } }); this._updateInstances(instances); diff --git a/GDJS/Runtime/RuntimeInstanceContainer.ts b/GDJS/Runtime/RuntimeInstanceContainer.ts index a8476a8235f5..e1320a0cc33c 100644 --- a/GDJS/Runtime/RuntimeInstanceContainer.ts +++ b/GDJS/Runtime/RuntimeInstanceContainer.ts @@ -396,6 +396,9 @@ namespace gdjs { .getVariables() .initFrom(instanceData.initialVariables, true); newObject.extraInitializationFromInitialInstance(instanceData); + if (this.getGame().isInGameEdition()) { + gdjs.RuntimeObject.applyInGameEditorMinimumOpacity(newObject); + } } } } diff --git a/GDJS/Runtime/debugger-client/hot-reloader.ts b/GDJS/Runtime/debugger-client/hot-reloader.ts index d13149ab219b..1708289cc2ad 100644 --- a/GDJS/Runtime/debugger-client/hot-reloader.ts +++ b/GDJS/Runtime/debugger-client/hot-reloader.ts @@ -1990,6 +1990,9 @@ namespace gdjs { ); if (numberPropertiesChanged || stringPropertiesChanged || sizeChanged) { runtimeObject.extraInitializationFromInitialInstance(newInstance); + if (this._runtimeGame.isInGameEdition()) { + gdjs.RuntimeObject.applyInGameEditorMinimumOpacity(runtimeObject); + } somethingChanged = true; } if (somethingChanged) { diff --git a/GDJS/Runtime/runtimeobject.ts b/GDJS/Runtime/runtimeobject.ts index da5ffd03374b..39819f5fb6b2 100644 --- a/GDJS/Runtime/runtimeobject.ts +++ b/GDJS/Runtime/runtimeobject.ts @@ -453,6 +453,22 @@ namespace gdjs { static supportsReinitialization = false; + /** + * Like in the 2D editor, transparent instances stay partially visible in + * the in-game editor so they can't be lost or misplaced. + */ + static applyInGameEditorMinimumOpacity(object: gdjs.RuntimeObject): void { + const objectWithOpacity = object as gdjs.RuntimeObject & + Partial; + if (!objectWithOpacity.getOpacity || !objectWithOpacity.setOpacity) { + return; + } + const minimumOpacity = 255 / 2; + if (objectWithOpacity.getOpacity() < minimumOpacity) { + objectWithOpacity.setOpacity(minimumOpacity); + } + } + /** * Return the time elapsed since the last frame, * in milliseconds, for the object.