diff --git a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs
index 540b602ec..837e7ad3b 100644
--- a/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs
+++ b/Source/Editor/CustomEditors/Dedicated/ActorEditor.cs
@@ -240,6 +240,12 @@ namespace FlaxEditor.CustomEditors.Dedicated
node.TextColor = Color.OrangeRed;
node.Text = Utilities.Utils.GetPropertyNameUI(removed.PrefabObject.GetType().Name);
}
+ // Removed Actor
+ else if (editor is RemovedActorDummy removedActor)
+ {
+ node.TextColor = Color.OrangeRed;
+ node.Text = $"{removedActor.PrefabObject.Name} ({Utilities.Utils.GetPropertyNameUI(removedActor.PrefabObject.GetType().Name)})";
+ }
// Actor or Script
else if (editor.Values[0] is SceneObject sceneObject)
{
@@ -295,11 +301,35 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Not used
}
}
+
+ private class RemovedActorDummy : CustomEditor
+ {
+ ///
+ /// The removed prefab object (from the prefab default instance).
+ ///
+ public Actor PrefabObject;
+
+ ///
+ /// The prefab instance's parent.
+ ///
+ public Actor ParentActor;
+
+ ///
+ /// The order of the removed actor in the parent.
+ ///
+ public int OrderInParent;
+
+ ///
+ public override void Initialize(LayoutElementsContainer layout)
+ {
+ // Not used
+ }
+ }
private TreeNode ProcessDiff(CustomEditor editor, bool skipIfNotModified = true)
{
- // Special case for new Script added to actor
- if (editor.Values[0] is Script script && !script.HasPrefabLink)
+ // Special case for new Script or child actor added to actor
+ if ((editor.Values[0] is Script script && !script.HasPrefabLink) || (editor.Values[0] is Actor a && !a.HasPrefabLink))
return CreateDiffNode(editor);
// Skip if no change detected
@@ -359,6 +389,41 @@ namespace FlaxEditor.CustomEditors.Dedicated
}
}
+ // Compare child actors for removed actors.
+ if (editor is ActorEditor && editor.Values.HasReferenceValue && editor.Values.ReferenceValue is Actor prefabObjectActor)
+ {
+ var thisActor = editor.Values[0] as Actor;
+ for (int i = 0; i < prefabObjectActor.ChildrenCount; i++)
+ {
+ var prefabActorChild = prefabObjectActor.Children[i];
+ if (thisActor == null)
+ continue;
+ bool isRemoved = true;
+ for (int j = 0; j < thisActor.ChildrenCount; j++)
+ {
+ var actorChild = thisActor.Children[j];
+ if (actorChild.PrefabObjectID == prefabActorChild.PrefabObjectID)
+ {
+ isRemoved = false;
+ break;
+ }
+ }
+ if (isRemoved)
+ {
+ var dummy = new RemovedActorDummy
+ {
+ PrefabObject = prefabActorChild,
+ ParentActor = thisActor,
+ OrderInParent = prefabActorChild.OrderInParent,
+ };
+ var child = CreateDiffNode(dummy);
+ if (result == null)
+ result = CreateDiffNode(editor);
+ result.AddChild(child);
+ }
+ }
+ }
+
return result;
}
@@ -459,6 +524,25 @@ namespace FlaxEditor.CustomEditors.Dedicated
return;
}
+ // Special case for reverting removed Actors
+ if (editor is RemovedActorDummy removedActor)
+ {
+ Editor.Log("Reverting removed actor changes to prefab (adding it)");
+
+ var parentActor = removedActor.ParentActor;
+ var restored = parentActor.AddChild(removedActor.PrefabObject.GetType());
+ var prefabId = parentActor.PrefabID;
+ var prefabObjectId = removedActor.PrefabObject.PrefabObjectID;
+ string data = JsonSerializer.Serialize(removedActor.PrefabObject);
+ JsonSerializer.Deserialize(restored, data);
+ if (Presenter.Owner is PropertiesWindow propertiesWindow)
+ Editor.Instance.SceneEditing.Spawn(restored, parentActor, removedActor.OrderInParent);
+ else if (Presenter.Owner is PrefabWindow prefabWindow)
+ prefabWindow.Spawn(restored, parentActor, removedActor.OrderInParent);
+ Actor.Internal_LinkPrefab(FlaxEngine.Object.GetUnmanagedPtr(restored), ref prefabId, ref prefabObjectId);
+ return;
+ }
+
// Special case for new Script added to actor
if (editor.Values[0] is Script script && !script.HasPrefabLink)
{
@@ -470,6 +554,27 @@ namespace FlaxEditor.CustomEditors.Dedicated
return;
}
+
+ // Special case for new Actor added to actor
+ if (editor.Values[0] is Actor a && !a.HasPrefabLink)
+ {
+ Editor.Log("Reverting added actor changes to prefab (removing it)");
+
+ // TODO: Keep previous selection.
+ if (Presenter.Owner is PropertiesWindow propertiesWindow)
+ {
+ var editorInstance = Editor.Instance.SceneEditing;
+ editorInstance.Select(a);
+ editorInstance.Delete();
+ }
+ else if (Presenter.Owner is PrefabWindow prefabWindow)
+ {
+ prefabWindow.Select(prefabWindow.Graph.Root.Find(a));
+ prefabWindow.Delete();
+ }
+
+ return;
+ }
editor.RevertToReferenceValue();
}