Fix undo for missing actor children and scripts when doing Convert action

This commit is contained in:
Wojtek Figat
2021-08-08 18:38:26 +02:00
parent 6609425880
commit cdca5b4a28
3 changed files with 48 additions and 25 deletions

View File

@@ -303,26 +303,28 @@ namespace FlaxEditor.Modules
{
if (!Editor.SceneEditing.HasSthSelected || !(Editor.SceneEditing.Selection[0] is ActorNode))
return;
if (Level.IsAnySceneLoaded == false)
throw new InvalidOperationException("Cannot spawn actor when no scene is loaded.");
var actionList = new IUndoAction[4];
Actor old = ((ActorNode)Editor.SceneEditing.Selection[0]).Actor;
Actor actor = (Actor)FlaxEngine.Object.New(to);
var oldNode = (ActorNode)Editor.SceneEditing.Selection[0];
var old = oldNode.Actor;
var actor = (Actor)FlaxEngine.Object.New(to);
var parent = old.Parent;
var orderInParent = old.OrderInParent;
// Steps:
// - deselect old actor
// - destroy old actor
// - spawn new actor
// - select new actor
SelectionDeleteBegin?.Invoke();
actionList[0] = new SelectionChangeAction(Selection.ToArray(), new SceneGraphNode[0], OnSelectionUndo);
actionList[0].Do();
actionList[1] = new DeleteActorsAction(new List<SceneGraphNode>
{
Editor.Instance.Scene.GetActorNode(old)
});
actionList[1].Do();
actionList[1] = new DeleteActorsAction(oldNode.BuildAllNodes().Where(x => x.CanDelete).ToList());
SelectionDeleteEnd?.Invoke();
@@ -345,17 +347,12 @@ namespace FlaxEditor.Modules
actor.StaticFlags = StaticFlags.None;
// Move children
for (var i = old.ScriptsCount - 1; i >= 0; i--)
{
var script = old.Scripts[i];
script.Actor = actor;
Guid newid = Guid.NewGuid();
FlaxEngine.Object.Internal_ChangeID(FlaxEngine.Object.GetUnmanagedPtr(script), ref newid);
}
for (var i = old.Children.Length - 1; i >= 0; i--)
{
old.Children[i].Parent = actor;
}
var scripts = old.Scripts;
for (var i = scripts.Length - 1; i >= 0; i--)
scripts[i].Actor = actor;
var children = old.Children;
for (var i = children.Length - 1; i >= 0; i--)
children[i].Parent = actor;
var actorNode = Editor.Instance.Scene.GetActorNode(actor);
if (actorNode == null)
@@ -364,16 +361,13 @@ namespace FlaxEditor.Modules
actorNode.PostSpawn();
Editor.Scene.MarkSceneEdited(actor.Scene);
actionList[2] = new DeleteActorsAction(new List<SceneGraphNode>
{
actorNode
}, true);
actionList[1].Do();
actionList[2] = new DeleteActorsAction(actorNode.BuildAllNodes().Where(x => x.CanDelete).ToList(), true);
actionList[3] = new SelectionChangeAction(new SceneGraphNode[0], new SceneGraphNode[] { actorNode }, OnSelectionUndo);
actionList[3].Do();
var actions = new MultiUndoAction(actionList);
Undo.AddAction(actions);
Undo.AddAction(new MultiUndoAction(actionList, "Convert actor"));
SpawnEnd?.Invoke();

View File

@@ -125,5 +125,33 @@ namespace FlaxEditor.SceneGraph
FillTree(target, result);
}
}
/// <summary>
/// Builds the list made of all nodes in the input scene tree root and child tree. The result collection contains all nodes in the tree.
/// </summary>
/// <param name="node">The node.</param>
/// <returns>The result.</returns>
public static List<SceneGraphNode> BuildAllNodes<T>(this T node)
where T : SceneGraphNode
{
var list = new List<SceneGraphNode>();
BuildAllNodes(node, list);
return list;
}
/// <summary>
/// Builds the list made of all nodes in the input scene tree root and child tree. The result collection contains all nodes in the tree.
/// </summary>
/// <param name="node">The node.</param>
/// <param name="result">The result.</param>
public static void BuildAllNodes<T>(this T node, List<SceneGraphNode> result)
where T : SceneGraphNode
{
if (node == null || result == null)
throw new ArgumentNullException();
result.Clear();
result.Add(node);
FillTree(node, result);
}
}
}

View File

@@ -135,6 +135,7 @@ namespace FlaxEditor.Actions
node.Delete();
}
_nodeParents.Clear();
FlaxEngine.Scripting.FlushRemovedObjects();
}
/// <summary>