mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-01-19 20:24:49 +00:00
Fixes issue where Regenerate Bounds button for SceneGroup/SubScenes wasn't displaying by moving it to Editing inspector group
Added mode toggle for if changing the transform influences the child objects of a SubScene or not Added onSelected/onUnselected callbacks for SimObjects to allow contextual behavior in the editor Added functionality of programmatic/dynamic Tool Button Palettes Added logic so when selecting SubScenes the world editor palette has new buttons for letting the move/rotate actions influence the child objects
This commit is contained in:
parent
10d1aeca1f
commit
e2d0cc1981
|
|
@ -119,7 +119,7 @@ void SceneGroup::onInspect(GuiInspector* inspector)
|
|||
Parent::onInspect(inspector);
|
||||
|
||||
//Put the SubScene group before everything that'd be SubScene-effecting, for orginazational purposes
|
||||
GuiInspectorGroup* sceneGroupGrp = inspector->findExistentGroup(StringTable->insert("SceneGroup"));
|
||||
GuiInspectorGroup* sceneGroupGrp = inspector->findExistentGroup(StringTable->insert("Editing"));
|
||||
if (!sceneGroupGrp)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
#include "gui/editor/inspector/group.h"
|
||||
#include "T3D/gameBase/gameBase.h"
|
||||
|
||||
bool SubScene::smTransformChildren = false;
|
||||
|
||||
IMPLEMENT_CO_NETOBJECT_V1(SubScene);
|
||||
|
||||
S32 SubScene::mUnloadTimeoutMs = 5000;
|
||||
|
|
@ -86,6 +88,10 @@ void SubScene::consoleInit()
|
|||
|
||||
Con::addVariable("$SubScene::UnloadTimeoutMS", TypeBool, &SubScene::mUnloadTimeoutMs, "The amount of time in milliseconds it takes for a SubScene to be unloaded if it's inactive.\n"
|
||||
"@ingroup Editors\n");
|
||||
|
||||
Con::addVariable("$SubScene::transformChildren", TypeBool, &SubScene::smTransformChildren,
|
||||
"@brief If true, then transform manipulations modify child objects. If false, only triggering bounds is manipulated\n\n"
|
||||
"@ingroup Editors");
|
||||
}
|
||||
|
||||
void SubScene::addObject(SimObject* object)
|
||||
|
|
@ -163,6 +169,30 @@ void SubScene::inspectPostApply()
|
|||
setMaskBits(-1);
|
||||
}
|
||||
|
||||
void SubScene::setTransform(const MatrixF& mat)
|
||||
{
|
||||
if(SubScene::smTransformChildren)
|
||||
{
|
||||
Parent::setTransform(mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneObject::setTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
void SubScene::setRenderTransform(const MatrixF& mat)
|
||||
{
|
||||
if (SubScene::smTransformChildren)
|
||||
{
|
||||
Parent::setRenderTransform(mat);
|
||||
}
|
||||
else
|
||||
{
|
||||
SceneObject::setRenderTransform(mat);
|
||||
}
|
||||
}
|
||||
|
||||
bool SubScene::evaluateCondition()
|
||||
{
|
||||
if (!mLoadIf.isEmpty())
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ public:
|
|||
|
||||
void onLevelChanged() {}
|
||||
|
||||
protected:
|
||||
static bool smTransformChildren;
|
||||
|
||||
private:
|
||||
DECLARE_LEVELASSET(SubScene, Level, onLevelChanged);
|
||||
|
||||
|
|
@ -47,6 +50,7 @@ private:
|
|||
U32 mCurrTick;
|
||||
|
||||
bool mGlobalLayer;
|
||||
|
||||
public:
|
||||
SubScene();
|
||||
virtual ~SubScene();
|
||||
|
|
@ -71,6 +75,9 @@ public:
|
|||
//void onEditorDisable() override;
|
||||
void inspectPostApply() override;
|
||||
|
||||
void setTransform(const MatrixF& mat) override;
|
||||
void setRenderTransform(const MatrixF& mat) override;
|
||||
|
||||
bool testBox(const Box3F& testBox);
|
||||
bool evaluateCondition();
|
||||
void _onSelected() override;
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ SimObjectId SimObject::smForcedId = 0;
|
|||
bool SimObject::preventNameChanging = false;
|
||||
|
||||
IMPLEMENT_CALLBACK(SimObject, onInspectPostApply, void, (SimObject* obj), (obj), "Generic callback for when an object is edited");
|
||||
IMPLEMENT_CALLBACK(SimObject, onSelected, void, (SimObject* obj), (obj), "Generic callback for when an object is selected");
|
||||
IMPLEMENT_CALLBACK(SimObject, onUnselected, void, (SimObject* obj), (obj), "Generic callback for when an object is un-selected");
|
||||
|
||||
namespace Sim
|
||||
{
|
||||
|
|
@ -527,6 +529,14 @@ bool SimObject::save(const char *pcFileName, bool bOnlySelected, const char *pre
|
|||
|
||||
}
|
||||
|
||||
bool SimObject::saveAppend(const char* pcFileName, bool bOnlySelected, const char* preappend)
|
||||
{
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SimPersistID* SimObject::getOrCreatePersistentId()
|
||||
|
|
@ -2207,11 +2217,13 @@ void SimObject::setSelected( bool sel )
|
|||
{
|
||||
mFlags.set( Selected );
|
||||
_onSelected();
|
||||
onSelected_callback(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFlags.clear( Selected );
|
||||
_onUnselected();
|
||||
onUnselected_callback(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -579,6 +579,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks
|
|||
|
||||
/// Save object as a TorqueScript File.
|
||||
virtual bool save( const char* pcFilePath, bool bOnlySelected = false, const char *preappend = NULL );
|
||||
virtual bool saveAppend(const char* pcFilePath, bool bOnlySelected = false, const char* preappend = NULL);
|
||||
|
||||
/// Check if a method exists in the objects current namespace.
|
||||
virtual bool isMethod( const char* methodName );
|
||||
|
|
@ -981,6 +982,8 @@ class SimObject: public ConsoleObject, public TamlCallbacks
|
|||
|
||||
DECLARE_CONOBJECT( SimObject );
|
||||
DECLARE_CALLBACK(void, onInspectPostApply, (SimObject* obj));
|
||||
DECLARE_CALLBACK(void, onSelected, (SimObject* obj));
|
||||
DECLARE_CALLBACK(void, onUnselected, (SimObject* obj));
|
||||
|
||||
static SimObject* __findObject( const char* id ) { return Sim::findObject( id ); }
|
||||
static const char* __getObjectId( ConsoleObject* object )
|
||||
|
|
|
|||
|
|
@ -1,33 +1,20 @@
|
|||
//--- OBJECT WRITE BEGIN ---
|
||||
new Scene(EditorTemplateLevel) {
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
Enabled = "1";
|
||||
isEditing = "1";
|
||||
enabled = "1";
|
||||
|
||||
new LevelInfo(theLevelInfo) {
|
||||
nearClip = "0.1";
|
||||
visibleDistance = "1000";
|
||||
visibleGhostDistance = "0";
|
||||
decalBias = "0.0015";
|
||||
fogColor = "0.6 0.6 0.7 1";
|
||||
fogDensity = "0";
|
||||
FogColor = "0.6 0.6 0.7 1";
|
||||
fogDensityOffset = "700";
|
||||
fogAtmosphereHeight = "0";
|
||||
canvasClearColor = "0 0 0 255";
|
||||
ambientLightBlendPhase = "1";
|
||||
ambientLightBlendCurve = "0 0 -1 -1";
|
||||
soundAmbience = "AudioAmbienceDefault";
|
||||
soundDistanceModel = "Linear";
|
||||
canSave = "1";
|
||||
canSaveDynamicFields = "1";
|
||||
Enabled = "1";
|
||||
enabled = "1";
|
||||
};
|
||||
new ScatterSky(DynamicSky) {
|
||||
sunScale = "0.991102 0.921582 0.83077 1";
|
||||
zOffset = "-3000";
|
||||
azimuth = "25";
|
||||
brightness = "5";
|
||||
flareType = "LightFlareExample1";
|
||||
MoonMatAsset = "Core_Rendering:moon_wglow";
|
||||
useNightCubemap = "1";
|
||||
nightCubemap = "nightCubemap";
|
||||
|
|
@ -44,16 +31,29 @@ new Scene(EditorTemplateLevel) {
|
|||
persistentId = "289ad401-3140-11ed-aae8-c0cb519281fc";
|
||||
reflectionPath = "tools/levels/DefaultEditorLevel/probes/";
|
||||
};
|
||||
|
||||
new GroundPlane() {
|
||||
scaleU = "32";
|
||||
scaleV = "32";
|
||||
MaterialAsset = "Prototyping:FloorGray";
|
||||
Enabled = "1";
|
||||
enabled = "1";
|
||||
position = "0 0 0";
|
||||
rotation = "1 0 0 0";
|
||||
scale = "1 1 1";
|
||||
};
|
||||
new SubScene() {
|
||||
LevelAsset = "Prototyping:PrefabTestSubScene";
|
||||
position = "4.38205 -5.66842 1.53303";
|
||||
scale = "33.0705 24.1137 4.59909";
|
||||
};
|
||||
new Trigger() {
|
||||
dataBlock = "DefaultTrigger";
|
||||
position = "0 0 -7.19786";
|
||||
scale = "15.3957 15.3957 15.3957";
|
||||
firstDataCheck = "1";
|
||||
};
|
||||
new Prefab() {
|
||||
fileName = "data/Prototyping/prefabs/testPrefab.prefab";
|
||||
};
|
||||
};
|
||||
//--- OBJECT WRITE END ---
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ $guiContent = new GuiControl() {
|
|||
minSize = "50 50";
|
||||
EdgeSnap = false;
|
||||
text = "";
|
||||
class = "EWToolsPaletteWindowClass";
|
||||
class = "ButtonPalette";
|
||||
|
||||
new GuiDynamicCtrlArrayControl(ToolsPaletteArray) {
|
||||
canSaveDynamicFields = "0";
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ function initializeWorldEditor()
|
|||
exec("./scripts/probeBake.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/visibility/visibilityLayer.ed." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/visibility/probeViz." @ $TorqueScriptFileExtension);
|
||||
exec("./scripts/buttonPalette." @ $TorqueScriptFileExtension);
|
||||
|
||||
exec("tools/gui/postFxEditor." @ $TorqueScriptFileExtension );
|
||||
exec("tools/gui/renderTargetVisualizer.ed." @ $TorqueScriptFileExtension);
|
||||
|
|
@ -77,6 +78,8 @@ function initializeWorldEditor()
|
|||
loadDirectory(expandFilename("./scripts/editors"));
|
||||
loadDirectory(expandFilename("./scripts/interfaces"));
|
||||
|
||||
exec("./scripts/interfaces/subSceneEditing.tscript");
|
||||
|
||||
// Create the default editor plugins before calling buildMenus.
|
||||
|
||||
new ScriptObject( WorldEditorPlugin )
|
||||
|
|
|
|||
|
|
@ -1069,11 +1069,13 @@ function WorldEditorInspectorPlugin::onWorldEditorStartup( %this )
|
|||
//connect editor windows
|
||||
GuiWindowCtrl::attach( EWInspectorWindow, EWTreeWindow);
|
||||
|
||||
%map = new ActionMap();
|
||||
%map = new ActionMap();
|
||||
|
||||
/*
|
||||
%map.bindCmd( keyboard, "1", "EWorldEditorNoneModeBtn.performClick();", "" ); // Select
|
||||
%map.bindCmd( keyboard, "2", "EWorldEditorMoveModeBtn.performClick();", "" ); // Move
|
||||
%map.bindCmd( keyboard, "3", "EWorldEditorRotateModeBtn.performClick();", "" ); // Rotate
|
||||
%map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale
|
||||
%map.bindCmd( keyboard, "4", "EWorldEditorScaleModeBtn.performClick();", "" ); // Scale*/
|
||||
%map.bindCmd( keyboard, "f", "FitToSelectionBtn.performClick();", "" );// Fit Camera to Selection
|
||||
%map.bindCmd( keyboard, "z", "EditorGuiStatusBar.setCamera(\"Standard Camera\");", "" );// Free camera
|
||||
%map.bindCmd( keyboard, "n", "ToggleNodeBar->renderHandleBtn.performClick();", "" );// Render Node
|
||||
|
|
@ -1093,21 +1095,38 @@ function WorldEditorInspectorPlugin::onWorldEditorStartup( %this )
|
|||
function WorldEditorInspectorPlugin::onActivated( %this )
|
||||
{
|
||||
Parent::onActivated( %this );
|
||||
|
||||
//Clears the button pallete stack
|
||||
EWToolsPaletteWindow.setStackCtrl(ToolsPaletteArray); //legacy ctrl adhereance
|
||||
EWToolsPaletteWindow.clearButtons();
|
||||
|
||||
EWToolsPaletteWindow.setActionMap(WorldEditorInspectorPlugin.map);
|
||||
|
||||
//Adds a button to the pallete stack
|
||||
//Name Icon Click Command Tooltip text Keybind
|
||||
EWToolsPaletteWindow.addButton("Select", "ToolsModule:arrow_n_image", "EWorldEditorNoneModeBtn::onClick();", "", "Select Arrow", "1");
|
||||
EWToolsPaletteWindow.addButton("Move", "ToolsModule:translate_n_image", "EWorldEditorMoveModeBtn::onClick();", "", "Move Selection", "2");
|
||||
EWToolsPaletteWindow.addButton("Rotate", "ToolsModule:rotate_n_image", "EWorldEditorRotateModeBtn::onClick();", "", "Rotate Selection", "3");
|
||||
EWToolsPaletteWindow.addButton("Scale", "ToolsModule:Scale_n_image", "EWorldEditorScaleModeBtn::onClick();", "", "Scale Selection", "4");
|
||||
|
||||
EWToolsPaletteWindow.refresh();
|
||||
|
||||
EditorGui-->InspectorWindow.setVisible( true );
|
||||
EditorGui-->TreeWindow.setVisible( true );
|
||||
EditorGui-->WorldEditorToolbar.setVisible( true );
|
||||
%this.map.push();
|
||||
//%this.map.push();
|
||||
}
|
||||
|
||||
function WorldEditorInspectorPlugin::onDeactivated( %this )
|
||||
{
|
||||
Parent::onDeactivated( %this );
|
||||
|
||||
EWToolsPaletteWindow.popActionMap();
|
||||
|
||||
EditorGui-->InspectorWindow.setVisible( false );
|
||||
EditorGui-->TreeWindow.setVisible( false );
|
||||
EditorGui-->WorldEditorToolbar.setVisible( false );
|
||||
%this.map.pop();
|
||||
//%this.map.pop();
|
||||
}
|
||||
|
||||
function WorldEditorInspectorPlugin::onEditMenuSelect( %this, %editMenu )
|
||||
|
|
|
|||
|
|
@ -0,0 +1,160 @@
|
|||
function ButtonPalette::setStackCtrl(%this, %ctrl)
|
||||
{
|
||||
%this.stackCtrl = %ctrl;
|
||||
}
|
||||
|
||||
function ButtonPalette::getStackCtrl(%this)
|
||||
{
|
||||
if(isObject(%this.stackCtrl))
|
||||
return %this.stackCtrl;
|
||||
else
|
||||
return %this;
|
||||
}
|
||||
|
||||
function ButtonPalette::setActionMap(%this, %actionMap)
|
||||
{
|
||||
%this.actionMap = %actionMap;
|
||||
%this.actionMap.push();
|
||||
}
|
||||
|
||||
function ButtonPalette::getActionMap(%this)
|
||||
{
|
||||
return %this.actionMap;
|
||||
}
|
||||
|
||||
function ButtonPalette::popActionMap(%this, %actionMap)
|
||||
{
|
||||
%this.actionMap.pop();
|
||||
}
|
||||
|
||||
function ButtonPalette::clearButtons(%this)
|
||||
{
|
||||
%stackCtrl = %this.getStackCtrl();
|
||||
%stackCtrl.clear();
|
||||
|
||||
for(%i=0; %i < %this.numButtons; %i++)
|
||||
{
|
||||
if(isObject(%this.actionMap))
|
||||
{
|
||||
%this.actionMap.unbind("keyboard", getField(%this.buttons[%i], 5));
|
||||
}
|
||||
|
||||
%this.buttons[%i] = "";
|
||||
}
|
||||
|
||||
%this.numButtons = 0;
|
||||
}
|
||||
|
||||
//Name, Icon, Click Command, Variable, Tooltip text, Keybind
|
||||
function ButtonPalette::addButton(%this, %name, %iconAsset, %command, %syncVariable, %toolTip, %keybind)
|
||||
{
|
||||
if(%this.numButtons $= "")
|
||||
%this.numButtons = 0;
|
||||
|
||||
for(%i=0; %i < %this.numButtons; %i++)
|
||||
{
|
||||
%buttonInfo = %this.buttons[%i];
|
||||
|
||||
//echo("Testing button info: " @ getField(%buttonInfo, 0) @ " against new button name: " @ %name);
|
||||
if(getField(%buttonInfo, 0) $= %name) //no duplicates
|
||||
return;
|
||||
}
|
||||
|
||||
%this.buttons[%this.numButtons] = %name TAB %iconAsset TAB %command TAB %syncVariable TAB %toolTip TAB %keybind;
|
||||
|
||||
%this.numButtons++;
|
||||
}
|
||||
|
||||
function ButtonPalette::removeButton(%this, %name)
|
||||
{
|
||||
%found = false;
|
||||
for(%i=0; %i < %this.numButtons; %i++)
|
||||
{
|
||||
if(getField(%this.buttons[%i], 0) $= %name)
|
||||
{
|
||||
%found = true;
|
||||
|
||||
if(isObject(%this.actionMap))
|
||||
{
|
||||
%this.actionMap.unbind("keyboard", getField(%this.buttons[%i], 5));
|
||||
}
|
||||
}
|
||||
|
||||
if(%found)
|
||||
{
|
||||
%this.buttons[%i] = %this.buttons[%i+1];
|
||||
}
|
||||
}
|
||||
|
||||
if(%found)
|
||||
%this.numButtons--;
|
||||
|
||||
return %found;
|
||||
}
|
||||
|
||||
function ButtonPalette::findButton(%this, %name)
|
||||
{
|
||||
%stackCtrl = %this.getStackCtrl();
|
||||
for(%i=0; %i < %stackCtrl.getCount(); %i++)
|
||||
{
|
||||
%btnObj = %stackCtrl.getObject(%i);
|
||||
|
||||
if(%btnObj.buttonName $= %name)
|
||||
return %btnObj;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function ButtonPalette::refresh(%this)
|
||||
{
|
||||
%stackCtrl = %this.getStackCtrl();
|
||||
%stackCtrl.clear();
|
||||
|
||||
%this.visible = true;
|
||||
%extents = "25 25";
|
||||
|
||||
if(%this.numButtons == 0)
|
||||
{
|
||||
%this.visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
for(%i=0; %i < %this.numButtons; %i++)
|
||||
{
|
||||
%buttonInfo = %this.buttons[%i];
|
||||
|
||||
%paletteButton = new GuiBitmapButtonCtrl() {
|
||||
canSaveDynamicFields = "0";
|
||||
internalName = getField(%buttonInfo, 0) @ "_paletteButton";
|
||||
Enabled = "1";
|
||||
isContainer = "0";
|
||||
Profile = "ToolsGuiButtonProfile";
|
||||
HorizSizing = "right";
|
||||
VertSizing = "bottom";
|
||||
Position = "0 0";
|
||||
Extent = "25 19";
|
||||
MinExtent = "8 2";
|
||||
canSave = "1";
|
||||
Visible = "1";
|
||||
tooltipprofile = "ToolsGuiToolTipProfile";
|
||||
ToolTip = getField(%buttonInfo, 4) SPC "(" @ getField(%buttonInfo, 5) @ ")";
|
||||
hovertime = "1000";
|
||||
bitmapAsset = getField(%buttonInfo, 1);
|
||||
buttonType = "RadioButton";
|
||||
useMouseEvents = "0";
|
||||
buttonName = getField(%buttonInfo, 0);
|
||||
command = getField(%buttonInfo, 2);
|
||||
variable = getField(%buttonInfo, 3);
|
||||
};
|
||||
|
||||
%extents.y += 23;
|
||||
|
||||
if(isObject(%this.actionMap))
|
||||
%this.actionMap.bindCmd( keyboard, getField(%buttonInfo, 5), %paletteButton @ ".performClick();", "" );
|
||||
|
||||
%stackCtrl.add(%paletteButton);
|
||||
}
|
||||
|
||||
%this.extent.y = %extents.y;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
function SubScene::onSelected(%this)
|
||||
{
|
||||
echo("SELECTED SUBSCENE");
|
||||
|
||||
%moveButton = EWToolsPaletteWindow.findButton("Move");
|
||||
%rotateButton = EWToolsPaletteWindow.findButton("Rotate");
|
||||
|
||||
%moveButton.originalCommand = %moveButton.command;
|
||||
%moveButton.command = "SubSceneMoveModeBtn::onClick();";
|
||||
|
||||
%rotateButton.originalCommand = %rotateButton.command;
|
||||
%rotateButton.command = "SubSceneRotateModeBtn::onClick();";
|
||||
|
||||
EWToolsPaletteWindow.addButton("SubSceneMove", "ToolsModule:translate_n_image", "SubSceneChildMoveModeBtn::onClick();", "", "Move SubScene + Children", "1");
|
||||
EWToolsPaletteWindow.addButton("SubSceneRotate", "ToolsModule:rotate_n_image", "SubSceneChildRotateModeBtn::onClick();", "", "Rotate SubScene + Children", "2");
|
||||
|
||||
EWToolsPaletteWindow.refresh();
|
||||
}
|
||||
|
||||
function SubScene::onUnselected(%this)
|
||||
{
|
||||
echo("UN-SELECTED SUBSCENE");
|
||||
EWToolsPaletteWindow.removeButton("SubSceneMove");
|
||||
EWToolsPaletteWindow.removeButton("SubSceneRotate");
|
||||
|
||||
%moveButton = EWToolsPaletteWindow.findButton("Move");
|
||||
%rotateButton = EWToolsPaletteWindow.findButton("Rotate");
|
||||
|
||||
%moveButton.command = %moveButton.originalCommand;
|
||||
%rotateButton.command = %rotateButton.originalCommand;
|
||||
|
||||
$SubScene::transformChildren = false;
|
||||
|
||||
EWToolsPaletteWindow.refresh();
|
||||
}
|
||||
|
||||
function SubSceneMoveModeBtn::onClick(%this)
|
||||
{
|
||||
EWorldEditorMoveModeBtn::onClick();
|
||||
$SubScene::transformChildren = false;
|
||||
}
|
||||
|
||||
function SubSceneRotateModeBtn::onClick(%this)
|
||||
{
|
||||
EWorldEditorRotateModeBtn::onClick();
|
||||
$SubScene::transformChildren = false;
|
||||
}
|
||||
|
||||
function SubSceneChildMoveModeBtn::onClick()
|
||||
{
|
||||
EWorldEditorMoveModeBtn::onClick();
|
||||
$SubScene::transformChildren = true;
|
||||
}
|
||||
|
||||
function SubSceneChildRotateModeBtn::onClick()
|
||||
{
|
||||
EWorldEditorRotateModeBtn::onClick();
|
||||
$SubScene::transformChildren = true;
|
||||
}
|
||||
Loading…
Reference in a new issue