From f306d34a6e953e81182617ea9c164036fa98d897 Mon Sep 17 00:00:00 2001 From: Chandler Cox Date: Tue, 23 Jan 2024 08:34:15 -0600 Subject: [PATCH] Add drag drop for actor script items into scenes and prefabs. --- Source/Editor/SceneGraph/GUI/ActorTreeNode.cs | 46 +++++++++++++++++++ .../Viewport/MainEditorGizmoViewport.cs | 11 ++++- .../Editor/Viewport/PrefabWindowViewport.cs | 11 ++++- .../Editor/Viewport/ViewportDraggingHelper.cs | 24 +++++++++- .../Windows/Assets/PrefabWindow.Hierarchy.cs | 40 ++++++++++++++++ Source/Editor/Windows/SceneTreeWindow.cs | 42 +++++++++++++++++ 6 files changed, 170 insertions(+), 4 deletions(-) diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index 9cfe5b7bd..d31955acc 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -29,6 +29,7 @@ namespace FlaxEditor.SceneGraph.GUI private DragScripts _dragScripts; private DragAssets _dragAssets; private DragActorType _dragActorType; + private DragScriptItems _dragScriptItems; private DragHandlers _dragHandlers; private List _highlights; private bool _hasSearchFilter; @@ -395,6 +396,13 @@ namespace FlaxEditor.SceneGraph.GUI } if (_dragActorType.OnDragEnter(data)) return _dragActorType.Effect; + if (_dragScriptItems == null) + { + _dragScriptItems = new DragScriptItems(ValidateDragScriptItem); + _dragHandlers.Add(_dragScriptItems); + } + if (_dragScriptItems.OnDragEnter(data)) + return _dragScriptItems.Effect; return DragDropEffect.None; } @@ -673,7 +681,37 @@ namespace FlaxEditor.SceneGraph.GUI actor.Transform = Actor.Transform; ActorNode.Root.Spawn(actor, Actor); } + result = DragDropEffect.Move; + } + // Drag script item + else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag) + { + var spawnParent = myActor; + if (DragOverMode == DragItemPositioning.Above || DragOverMode == DragItemPositioning.Below) + spawnParent = newParent; + for (int i = 0; i < _dragScriptItems.Objects.Count; i++) + { + var item = _dragScriptItems.Objects[i]; + // Find actors with the same content item and spawn them. + foreach (var actorType in Editor.Instance.CodeEditing.Actors.Get()) + { + if (actorType.ContentItem != item) + continue; + + var actor = actorType.CreateInstance() as Actor; + if (actor == null) + { + Editor.LogWarning("Failed to spawn actor of type " + actorType.TypeName); + continue; + } + actor.StaticFlags = spawnParent.StaticFlags; + actor.Name = actorType.Name; + actor.Transform = spawnParent.Transform; + ActorNode.Root.Spawn(actor, spawnParent); + actor.OrderInParent = newOrder; + } + } result = DragDropEffect.Move; } @@ -728,6 +766,14 @@ namespace FlaxEditor.SceneGraph.GUI return true; } + private static bool ValidateDragScriptItem(ScriptItem script) + { + var actors = Editor.Instance.CodeEditing.Actors.Get(); + if (actors.Any(x => x.ContentItem == script)) + return true; + return false; + } + /// protected override void DoDragDrop() { diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index 24c8f1c4c..c501def33 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using FlaxEditor.Content; using FlaxEditor.Gizmo; using FlaxEditor.GUI.ContextMenu; @@ -194,7 +195,7 @@ namespace FlaxEditor.Viewport : base(Object.New(), editor.Undo, editor.Scene.Root) { _editor = editor; - DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType); + DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType, ValidateDragScriptItem); var inputOptions = editor.Options.Options.Input; // Prepare rendering task @@ -940,6 +941,14 @@ namespace FlaxEditor.Viewport return Level.IsAnySceneLoaded; } + private static bool ValidateDragScriptItem(ScriptItem script) + { + var actors = Editor.Instance.CodeEditing.Actors.Get(); + if (actors.Any(x => x.ContentItem == script)) + return true; + return false; + } + /// public override DragDropEffect OnDragMove(ref Float2 location, DragData data) { diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index 6e111f588..a46002028 100644 --- a/Source/Editor/Viewport/PrefabWindowViewport.cs +++ b/Source/Editor/Viewport/PrefabWindowViewport.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using FlaxEditor.Content; using FlaxEditor.Gizmo; using FlaxEditor.GUI.ContextMenu; @@ -81,7 +82,7 @@ namespace FlaxEditor.Viewport _window.SelectionChanged += OnSelectionChanged; Undo = window.Undo; ViewportCamera = new FPSCamera(); - DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType); + DragHandlers = new ViewportDragHandlers(this, this, ValidateDragItem, ValidateDragActorType, ValidateDragScriptItem); ShowDebugDraw = true; ShowEditorPrimitives = true; Gizmos = new GizmosCollection(this); @@ -701,6 +702,14 @@ namespace FlaxEditor.Viewport { return true; } + + private static bool ValidateDragScriptItem(ScriptItem script) + { + var actors = Editor.Instance.CodeEditing.Actors.Get(); + if (actors.Any(x => x.ContentItem == script)) + return true; + return false; + } /// public override DragDropEffect OnDragMove(ref Float2 location, DragData data) diff --git a/Source/Editor/Viewport/ViewportDraggingHelper.cs b/Source/Editor/Viewport/ViewportDraggingHelper.cs index 8a1b4f183..83c9cfab0 100644 --- a/Source/Editor/Viewport/ViewportDraggingHelper.cs +++ b/Source/Editor/Viewport/ViewportDraggingHelper.cs @@ -39,17 +39,19 @@ namespace FlaxEditor.Viewport private readonly EditorViewport _viewport; private readonly DragAssets _dragAssets; private readonly DragActorType _dragActorType; + private readonly DragScriptItems _dragScriptItem; private StaticModel _previewStaticModel; private int _previewModelEntryIndex; private BrushSurface _previewBrushSurface; - internal ViewportDragHandlers(IGizmoOwner owner, EditorViewport viewport, Func validateAsset, Func validateDragActorType) + internal ViewportDragHandlers(IGizmoOwner owner, EditorViewport viewport, Func validateAsset, Func validateDragActorType, Func validateDragScriptItem) { _owner = owner; _viewport = viewport; Add(_dragAssets = new DragAssets(validateAsset)); Add(_dragActorType = new DragActorType(validateDragActorType)); + Add(_dragScriptItem = new DragScriptItems(validateDragScriptItem)); } internal void ClearDragEffects() @@ -102,7 +104,13 @@ namespace FlaxEditor.Viewport foreach (var actorType in _dragActorType.Objects) Spawn(actorType, hit, ref location, ref hitLocation, ref hitNormal); } - + else if (_dragScriptItem.HasValidDrag) + { + result = _dragScriptItem.Effect; + foreach (var scripItem in _dragScriptItem.Objects) + Spawn(scripItem, hit, ref location, ref hitLocation, ref hitNormal); + } + Debug.Log("Hit"); OnDragDrop(new DragDropEventArgs { Hit = hit, HitLocation = hitLocation }); return result; @@ -193,6 +201,18 @@ namespace FlaxEditor.Viewport _viewport.Focus(); } + private void Spawn(ScriptItem item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation, ref Vector3 hitNormal) + { + // Find actors with the same content item and spawn them. + foreach (var actorType in Editor.Instance.CodeEditing.Actors.Get()) + { + if (actorType.ContentItem != item) + continue; + + Spawn(actorType, hit, ref location, ref hitLocation, ref hitNormal); + } + } + private void Spawn(ScriptType item, SceneGraphNode hit, ref Float2 location, ref Vector3 hitLocation, ref Vector3 hitNormal) { var actor = item.CreateInstance() as Actor; diff --git a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs index f263d4734..1cf5fb40b 100644 --- a/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs +++ b/Source/Editor/Windows/Assets/PrefabWindow.Hierarchy.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using FlaxEditor.Content; using FlaxEditor.GUI.ContextMenu; using FlaxEditor.GUI.Drag; @@ -64,6 +65,7 @@ namespace FlaxEditor.Windows.Assets private PrefabWindow _window; private DragAssets _dragAssets; private DragActorType _dragActorType; + private DragScriptItems _dragScriptItems; private DragHandlers _dragHandlers; public SceneTreePanel(PrefabWindow window) @@ -83,6 +85,14 @@ namespace FlaxEditor.Windows.Assets { return true; } + + private static bool ValidateDragScriptItem(ScriptItem script) + { + var actors = Editor.Instance.CodeEditing.Actors.Get(); + if (actors.Any(x => x.ContentItem == script)) + return true; + return false; + } /// public override DragDropEffect OnDragEnter(ref Float2 location, DragData data) @@ -106,6 +116,13 @@ namespace FlaxEditor.Windows.Assets } if (_dragActorType.OnDragEnter(data)) return _dragActorType.Effect; + if (_dragScriptItems == null) + { + _dragScriptItems = new DragScriptItems(ValidateDragScriptItem); + _dragHandlers.Add(_dragScriptItems); + } + if (_dragScriptItems.OnDragEnter(data)) + return _dragScriptItems.Effect; } return result; } @@ -162,7 +179,30 @@ namespace FlaxEditor.Windows.Assets } result = DragDropEffect.Move; } + // Drag script item + else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag) + { + for (int i = 0; i < _dragScriptItems.Objects.Count; i++) + { + var item = _dragScriptItems.Objects[i]; + // Find actors with the same content item and spawn them. + foreach (var actorType in Editor.Instance.CodeEditing.Actors.Get()) + { + if (actorType.ContentItem != item) + continue; + var actor = actorType.CreateInstance() as Actor; + if (actor == null) + { + Editor.LogWarning("Failed to spawn actor of type " + actorType.TypeName); + continue; + } + actor.Name = actorType.Name; + _window.Spawn(actor); + } + } + result = DragDropEffect.Move; + } _dragHandlers.OnDragDrop(null); } return result; diff --git a/Source/Editor/Windows/SceneTreeWindow.cs b/Source/Editor/Windows/SceneTreeWindow.cs index 63ba7b960..c1390a1fe 100644 --- a/Source/Editor/Windows/SceneTreeWindow.cs +++ b/Source/Editor/Windows/SceneTreeWindow.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Linq; using FlaxEditor.Gizmo; using FlaxEditor.Content; using FlaxEditor.GUI.Tree; @@ -31,6 +32,7 @@ namespace FlaxEditor.Windows private DragAssets _dragAssets; private DragActorType _dragActorType; + private DragScriptItems _dragScriptItems; private DragHandlers _dragHandlers; /// @@ -272,6 +274,14 @@ namespace FlaxEditor.Windows { return true; } + + private static bool ValidateDragScriptItem(ScriptItem script) + { + var actors = Editor.Instance.CodeEditing.Actors.Get(); + if (actors.Any(x => x.ContentItem == script)) + return true; + return false; + } /// public override void Draw() @@ -380,6 +390,13 @@ namespace FlaxEditor.Windows } if (_dragActorType.OnDragEnter(data) && result == DragDropEffect.None) return _dragActorType.Effect; + if (_dragScriptItems == null) + { + _dragScriptItems = new DragScriptItems(ValidateDragScriptItem); + _dragHandlers.Add(_dragScriptItems); + } + if (_dragScriptItems.OnDragEnter(data) && result == DragDropEffect.None) + return _dragScriptItems.Effect; } return result; } @@ -445,6 +462,31 @@ namespace FlaxEditor.Windows } result = DragDropEffect.Move; } + // Drag script item + else if (_dragScriptItems != null && _dragScriptItems.HasValidDrag) + { + for (int i = 0; i < _dragScriptItems.Objects.Count; i++) + { + var item = _dragScriptItems.Objects[i]; + // Find actors with the same content item and spawn them. + foreach (var actorType in Editor.Instance.CodeEditing.Actors.Get()) + { + if (actorType.ContentItem != item) + continue; + + var actor = actorType.CreateInstance() as Actor; + if (actor == null) + { + Editor.LogWarning("Failed to spawn actor of type " + actorType.TypeName); + continue; + } + actor.Name = actorType.Name; + Level.SpawnActor(actor); + Editor.Scene.MarkSceneEdited(actor.Scene); + } + } + result = DragDropEffect.Move; + } _dragHandlers.OnDragDrop(null); }