diff --git a/Source/Editor/SceneGraph/ActorNode.cs b/Source/Editor/SceneGraph/ActorNode.cs
index 3542feb03..6703c30a0 100644
--- a/Source/Editor/SceneGraph/ActorNode.cs
+++ b/Source/Editor/SceneGraph/ActorNode.cs
@@ -288,6 +288,13 @@ namespace FlaxEditor.SceneGraph
{
}
+ ///
+ /// Action called after pasting actor in editor.
+ ///
+ public virtual void PostPaste()
+ {
+ }
+
///
protected override void OnParentChanged()
{
diff --git a/Source/Editor/SceneGraph/Actors/UIControlNode.cs b/Source/Editor/SceneGraph/Actors/UIControlNode.cs
index b3f8f5d09..c4f7d1c17 100644
--- a/Source/Editor/SceneGraph/Actors/UIControlNode.cs
+++ b/Source/Editor/SceneGraph/Actors/UIControlNode.cs
@@ -25,5 +25,20 @@ namespace FlaxEditor.SceneGraph.Actors
if (Actor is UIControl uiControl)
DebugDraw.DrawWireBox(uiControl.Bounds, Color.BlueViolet);
}
+
+ ///
+ public override void PostPaste()
+ {
+ base.PostPaste();
+
+ var control = ((UIControl)Actor).Control;
+ if (control != null)
+ {
+ if (control.Parent != null)
+ control.Parent.PerformLayout();
+ else
+ control.PerformLayout();
+ }
+ }
}
}
diff --git a/Source/Editor/Undo/Actions/PasteActorsAction.cs b/Source/Editor/Undo/Actions/PasteActorsAction.cs
index c65aa6bf0..c77feb71d 100644
--- a/Source/Editor/Undo/Actions/PasteActorsAction.cs
+++ b/Source/Editor/Undo/Actions/PasteActorsAction.cs
@@ -140,22 +140,27 @@ namespace FlaxEditor.Actions
for (int i = 0; i < nodeParents.Count; i++)
{
- // Fix name collisions (only for parents)
var node = nodeParents[i];
var parent = node.Actor?.Parent;
if (parent != null)
{
+ // Fix name collisions
string name = node.Name;
Actor[] children = parent.Children;
if (children.Any(x => x.Name == name))
{
- // Generate new name
node.Actor.Name = StringUtils.IncrementNameNumber(name, x => children.All(y => y.Name != x));
}
}
Editor.Instance.Scene.MarkSceneEdited(node.ParentScene);
}
+
+ for (int i = 0; i < nodeParents.Count; i++)
+ {
+ var node = nodeParents[i];
+ node.PostPaste();
+ }
}
///
diff --git a/Source/Engine/Level/Actor.cpp b/Source/Engine/Level/Actor.cpp
index 21e2ae050..93f5c05c6 100644
--- a/Source/Engine/Level/Actor.cpp
+++ b/Source/Engine/Level/Actor.cpp
@@ -16,6 +16,7 @@
#include "Engine/Core/Collections/CollectionPoolCache.h"
#include "Engine/Debug/Exceptions/JsonParseException.h"
#include "Engine/Graphics/RenderView.h"
+#include "Engine/Profiler/ProfilerCPU.h"
#include "Engine/Scripting/Scripting.h"
#include "Engine/Serialization/ISerializeModifier.h"
#include "Engine/Serialization/Serialization.h"
@@ -1494,6 +1495,7 @@ void WriteObjectToBytes(SceneObject* obj, rapidjson_flax::StringBuffer& buffer,
bool Actor::ToBytes(const Array& actors, MemoryWriteStream& output)
{
+ PROFILE_CPU();
if (actors.IsEmpty())
{
// Cannot serialize empty list
@@ -1553,6 +1555,7 @@ Array Actor::ToBytes(const Array& actors)
bool Actor::FromBytes(const Span& data, Array& output, ISerializeModifier* modifier)
{
+ PROFILE_CPU();
output.Clear();
ASSERT(modifier);
@@ -1654,17 +1657,19 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM
Scripting::ObjectsLookupIdMapping.Set(nullptr);
// Link objects
- for (int32 i = 0; i < objectsCount; i++)
+ //for (int32 i = 0; i < objectsCount; i++)
{
- SceneObject* obj = sceneObjects->At(i);
- obj->PostLoad();
+ //SceneObject* obj = sceneObjects->At(i);
+ // TODO: post load or post spawn?
+ //obj->PostLoad();
}
// Update objects order
- for (int32 i = 0; i < objectsCount; i++)
+ //for (int32 i = 0; i < objectsCount; i++)
{
- SceneObject* obj = sceneObjects->At(i);
- obj->SetOrderInParent(order[i]);
+ //SceneObject* obj = sceneObjects->At(i);
+ // TODO: remove order from saved data?
+ //obj->SetOrderInParent(order[i]);
}
// Call events (only for parents because they will propagate events down the tree)
@@ -1681,6 +1686,10 @@ bool Actor::FromBytes(const Span& data, Array& output, ISerializeM
}
}
for (int32 i = 0; i < parents->Count(); i++)
+ {
+ parents->At(i)->PostSpawn();
+ }
+ for (int32 i = 0; i < parents->Count(); i++)
{
Actor* actor = parents->At(i);
actor->OnTransformChanged();
@@ -1722,6 +1731,7 @@ Array Actor::FromBytes(const Span& data, const Dictionary Actor::TryGetSerializedObjectsIds(const Span& data)
{
+ PROFILE_CPU();
Array result;
if (data.Length() > 0)
{
@@ -1742,6 +1752,7 @@ Array Actor::TryGetSerializedObjectsIds(const Span& data)
String Actor::ToJson()
{
+ PROFILE_CPU();
rapidjson_flax::StringBuffer buffer;
CompactJsonWriter writer(buffer);
writer.SceneObject(this);
@@ -1753,6 +1764,8 @@ String Actor::ToJson()
void Actor::FromJson(const StringAnsiView& json)
{
+ PROFILE_CPU();
+
// Load JSON
rapidjson_flax::Document document;
document.Parse(json.Get(), json.Length());
diff --git a/Source/Engine/UI/UIControl.cs b/Source/Engine/UI/UIControl.cs
index b8f8b00dd..d981c1b6c 100644
--- a/Source/Engine/UI/UIControl.cs
+++ b/Source/Engine/UI/UIControl.cs
@@ -52,7 +52,6 @@ namespace FlaxEngine
_control.Parent = GetParent();
_control.IndexInParent = OrderInParent;
_control.Location = new Vector2(LocalPosition);
- // TODO: sync control order in parent with actor order in parent (think about special cases like Panel with scroll bars used as internal controls)
_control.LocationChanged += OnControlLocationChanged;
// Link children UI controls
@@ -353,6 +352,7 @@ namespace FlaxEngine
if (_control != null)
{
_control.Parent = GetParent();
+ _control.IndexInParent = OrderInParent;
}
}