From 2c7d62bb8e5d517641074483cc713fe78b138b12 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 24 May 2021 18:34:19 +0200 Subject: [PATCH] Add support for custom drag&drop into level/prefab viewports from custom asset items --- Source/Editor/Content/Items/AssetItem.cs | 20 +++ .../Editor/Content/Items/BinaryAssetItem.cs | 32 +++- Source/Editor/Content/Items/PrefabItem.cs | 12 ++ .../Editor/Content/Items/VisualScriptItem.cs | 12 ++ Source/Editor/Content/Proxy/AudioClipProxy.cs | 49 +++++- .../Editor/Content/Proxy/BinaryAssetProxy.cs | 8 +- .../Content/Proxy/CollisionDataProxy.cs | 33 +++- Source/Editor/Content/Proxy/ModelProxy.cs | 2 +- .../Content/Proxy/ParticleSystemProxy.cs | 31 ++++ .../Content/Proxy/SceneAnimationProxy.cs | 31 ++++ Source/Editor/SceneGraph/GUI/ActorTreeNode.cs | 161 +----------------- .../Viewport/MainEditorGizmoViewport.cs | 148 ++++------------ .../Editor/Viewport/PrefabWindowViewport.cs | 85 +-------- 13 files changed, 262 insertions(+), 362 deletions(-) diff --git a/Source/Editor/Content/Items/AssetItem.cs b/Source/Editor/Content/Items/AssetItem.cs index afb68d42a..f534e93eb 100644 --- a/Source/Editor/Content/Items/AssetItem.cs +++ b/Source/Editor/Content/Items/AssetItem.cs @@ -108,6 +108,26 @@ namespace FlaxEditor.Content return false; } + /// + /// Called when user dags this item into editor viewport or scene tree node. + /// + /// The editor context (eg. editor viewport or scene tree node). + /// True if item can be dropped in, otherwise false. + public virtual bool OnEditorDrag(object context) + { + return false; + } + + /// + /// Called when user drops the item into editor viewport or scene tree node. + /// + /// The editor context (eg. editor viewport or scene tree node). + /// The spawned object. + public virtual Actor OnEditorDrop(object context) + { + throw new NotSupportedException($"Asset {GetType()} doesn't support dropping into viewport."); + } + /// protected override bool DrawShadow => true; diff --git a/Source/Editor/Content/Items/BinaryAssetItem.cs b/Source/Editor/Content/Items/BinaryAssetItem.cs index 417bd23e4..2503e9a38 100644 --- a/Source/Editor/Content/Items/BinaryAssetItem.cs +++ b/Source/Editor/Content/Items/BinaryAssetItem.cs @@ -103,14 +103,26 @@ namespace FlaxEditor.Content /// Implementation of for assets. /// /// - public class ModelAssetItem : BinaryAssetItem + public class ModelItem : BinaryAssetItem { /// - public ModelAssetItem(string path, ref Guid id, string typeName, Type type) + public ModelItem(string path, ref Guid id, string typeName, Type type) : base(path, ref id, typeName, type, ContentItemSearchFilter.Model) { } + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new StaticModel { Model = FlaxEngine.Content.LoadAsync(ID) }; + } + /// protected override void OnBuildTooltipText(StringBuilder sb) { @@ -142,14 +154,26 @@ namespace FlaxEditor.Content /// Implementation of for assets. /// /// - public class SkinnedModelAssetItem : BinaryAssetItem + public class SkinnedModeItem : BinaryAssetItem { /// - public SkinnedModelAssetItem(string path, ref Guid id, string typeName, Type type) + public SkinnedModeItem(string path, ref Guid id, string typeName, Type type) : base(path, ref id, typeName, type, ContentItemSearchFilter.Model) { } + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new AnimatedModel { SkinnedModel = FlaxEngine.Content.LoadAsync(ID) }; + } + /// protected override void OnBuildTooltipText(StringBuilder sb) { diff --git a/Source/Editor/Content/Items/PrefabItem.cs b/Source/Editor/Content/Items/PrefabItem.cs index aee264d55..e758595ae 100644 --- a/Source/Editor/Content/Items/PrefabItem.cs +++ b/Source/Editor/Content/Items/PrefabItem.cs @@ -21,6 +21,18 @@ namespace FlaxEditor.Content { } + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return PrefabManager.SpawnPrefab(FlaxEngine.Content.LoadAsync(ID), null); + } + /// public override ContentItemType ItemType => ContentItemType.Asset; diff --git a/Source/Editor/Content/Items/VisualScriptItem.cs b/Source/Editor/Content/Items/VisualScriptItem.cs index 04311644b..c1ccf5d73 100644 --- a/Source/Editor/Content/Items/VisualScriptItem.cs +++ b/Source/Editor/Content/Items/VisualScriptItem.cs @@ -538,6 +538,18 @@ namespace FlaxEditor.Content Editor.Instance.CodeEditing.ClearTypes(); } + /// + public override bool OnEditorDrag(object context) + { + return new ScriptType(typeof(Actor)).IsAssignableFrom(ScriptType) && ScriptType.CanCreateInstance; + } + + /// + public override Actor OnEditorDrop(object context) + { + return (Actor)ScriptType.CreateInstance(); + } + /// public override SpriteHandle DefaultThumbnail => Editor.Instance.Icons.VisualScript128; diff --git a/Source/Editor/Content/Proxy/AudioClipProxy.cs b/Source/Editor/Content/Proxy/AudioClipProxy.cs index ba60d6ef9..ceff22dd1 100644 --- a/Source/Editor/Content/Proxy/AudioClipProxy.cs +++ b/Source/Editor/Content/Proxy/AudioClipProxy.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; +using System.Text; using FlaxEditor.Content.Thumbnails; using FlaxEditor.Viewport.Previews; using FlaxEditor.Windows; @@ -11,11 +12,51 @@ using FlaxEngine.GUI; namespace FlaxEditor.Content { + /// + /// Implementation of for assets. + /// + /// + class AudioClipItem : BinaryAssetItem + { + /// + public AudioClipItem(string path, ref Guid id, string typeName, Type type) + : base(path, ref id, typeName, type, ContentItemSearchFilter.Audio) + { + } + + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new AudioSource { Clip = FlaxEngine.Content.LoadAsync(ID) }; + } + + /// + protected override void OnBuildTooltipText(StringBuilder sb) + { + base.OnBuildTooltipText(sb); + + var asset = FlaxEngine.Content.Load(ID, 100); + if (asset) + { + var info = asset.Info; + sb.Append("Duration: ").Append(asset.Length).AppendLine(); + sb.Append("Channels: ").Append(info.NumChannels).AppendLine(); + sb.Append("Bit Depth: ").Append(info.BitDepth).AppendLine(); + } + } + } + /// /// A asset proxy object. /// /// - public class AudioClipProxy : BinaryAssetProxy + class AudioClipProxy : BinaryAssetProxy { private List _previews; @@ -34,6 +75,12 @@ namespace FlaxEditor.Content return new AudioClipWindow(editor, (AssetItem)item); } + /// + public override AssetItem ConstructItem(string path, string typeName, ref Guid id) + { + return new AudioClipItem(path, ref id, typeName, AssetType); + } + /// public override Color AccentColor => Color.FromRGB(0xB3452B); diff --git a/Source/Editor/Content/Proxy/BinaryAssetProxy.cs b/Source/Editor/Content/Proxy/BinaryAssetProxy.cs index 4d27f325b..d19f8fd63 100644 --- a/Source/Editor/Content/Proxy/BinaryAssetProxy.cs +++ b/Source/Editor/Content/Proxy/BinaryAssetProxy.cs @@ -47,9 +47,9 @@ namespace FlaxEditor.Content if (typeof(TextureBase).IsAssignableFrom(type)) return new TextureAssetItem(path, ref id, typeName, type); if (typeof(Model).IsAssignableFrom(type)) - return new ModelAssetItem(path, ref id, typeName, type); + return new ModelItem(path, ref id, typeName, type); if (typeof(SkinnedModel).IsAssignableFrom(type)) - return new SkinnedModelAssetItem(path, ref id, typeName, type); + return new SkinnedModeItem(path, ref id, typeName, type); ContentItemSearchFilter searchFilter; if (typeof(MaterialBase).IsAssignableFrom(type)) @@ -58,11 +58,9 @@ namespace FlaxEditor.Content searchFilter = ContentItemSearchFilter.Prefab; else if (typeof(SceneAsset).IsAssignableFrom(type)) searchFilter = ContentItemSearchFilter.Scene; - else if (typeof(AudioClip).IsAssignableFrom(type)) - searchFilter = ContentItemSearchFilter.Audio; else if (typeof(Animation).IsAssignableFrom(type)) searchFilter = ContentItemSearchFilter.Animation; - else if (typeof(ParticleEmitter).IsAssignableFrom(type) || typeof(ParticleSystem).IsAssignableFrom(type)) + else if (typeof(ParticleEmitter).IsAssignableFrom(type)) searchFilter = ContentItemSearchFilter.Particles; else searchFilter = ContentItemSearchFilter.Other; diff --git a/Source/Editor/Content/Proxy/CollisionDataProxy.cs b/Source/Editor/Content/Proxy/CollisionDataProxy.cs index c23730375..e7d437adc 100644 --- a/Source/Editor/Content/Proxy/CollisionDataProxy.cs +++ b/Source/Editor/Content/Proxy/CollisionDataProxy.cs @@ -8,11 +8,36 @@ using FlaxEngine; namespace FlaxEditor.Content { + /// + /// Implementation of for assets. + /// + /// + class CollisionDataItem : BinaryAssetItem + { + /// + public CollisionDataItem(string path, ref Guid id, string typeName, Type type) + : base(path, ref id, typeName, type, ContentItemSearchFilter.Other) + { + } + + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new MeshCollider { CollisionData = FlaxEngine.Content.LoadAsync(ID) }; + } + } + /// /// A asset proxy object. /// /// - public class CollisionDataProxy : BinaryAssetProxy + class CollisionDataProxy : BinaryAssetProxy { /// public override string Name => "Collision Data"; @@ -23,6 +48,12 @@ namespace FlaxEditor.Content return new CollisionDataWindow(editor, item as AssetItem); } + /// + public override AssetItem ConstructItem(string path, string typeName, ref Guid id) + { + return new CollisionDataItem(path, ref id, typeName, AssetType); + } + /// public override Color AccentColor => Color.FromRGB(0x2c3e50); diff --git a/Source/Editor/Content/Proxy/ModelProxy.cs b/Source/Editor/Content/Proxy/ModelProxy.cs index a28a022a8..2baf717e1 100644 --- a/Source/Editor/Content/Proxy/ModelProxy.cs +++ b/Source/Editor/Content/Proxy/ModelProxy.cs @@ -47,7 +47,7 @@ namespace FlaxEditor.Content menu.AddButton("Create collision data", () => { - var model = FlaxEngine.Content.LoadAsync(((ModelAssetItem)item).ID); + var model = FlaxEngine.Content.LoadAsync(((ModelItem)item).ID); var collisionDataProxy = (CollisionDataProxy)Editor.Instance.ContentDatabase.GetProxy(); collisionDataProxy.CreateCollisionDataFromModel(model); }); diff --git a/Source/Editor/Content/Proxy/ParticleSystemProxy.cs b/Source/Editor/Content/Proxy/ParticleSystemProxy.cs index f3b2eb67a..7e206fba9 100644 --- a/Source/Editor/Content/Proxy/ParticleSystemProxy.cs +++ b/Source/Editor/Content/Proxy/ParticleSystemProxy.cs @@ -10,6 +10,31 @@ using FlaxEngine.GUI; namespace FlaxEditor.Content { + /// + /// Implementation of for assets. + /// + /// + class ParticleSystemItem : BinaryAssetItem + { + /// + public ParticleSystemItem(string path, ref Guid id, string typeName, Type type) + : base(path, ref id, typeName, type, ContentItemSearchFilter.Particles) + { + } + + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new ParticleEffect { ParticleSystem = FlaxEngine.Content.LoadAsync(ID) }; + } + } + /// /// A asset proxy object. /// @@ -28,6 +53,12 @@ namespace FlaxEditor.Content return new ParticleSystemWindow(editor, item as AssetItem); } + /// + public override AssetItem ConstructItem(string path, string typeName, ref Guid id) + { + return new ParticleSystemItem(path, ref id, typeName, AssetType); + } + /// public override Color AccentColor => Color.FromRGB(0xFF790200); diff --git a/Source/Editor/Content/Proxy/SceneAnimationProxy.cs b/Source/Editor/Content/Proxy/SceneAnimationProxy.cs index 83d9247d8..66c1bfff2 100644 --- a/Source/Editor/Content/Proxy/SceneAnimationProxy.cs +++ b/Source/Editor/Content/Proxy/SceneAnimationProxy.cs @@ -7,6 +7,31 @@ using FlaxEngine; namespace FlaxEditor.Content { + /// + /// Implementation of for assets. + /// + /// + class SceneAnimationItem : BinaryAssetItem + { + /// + public SceneAnimationItem(string path, ref Guid id, string typeName, Type type) + : base(path, ref id, typeName, type, ContentItemSearchFilter.Other) + { + } + + /// + public override bool OnEditorDrag(object context) + { + return true; + } + + /// + public override Actor OnEditorDrop(object context) + { + return new SceneAnimationPlayer { Animation = FlaxEngine.Content.LoadAsync(ID) }; + } + } + /// /// A asset proxy object. /// @@ -22,6 +47,12 @@ namespace FlaxEditor.Content return new SceneAnimationWindow(editor, item as AssetItem); } + /// + public override AssetItem ConstructItem(string path, string typeName, ref Guid id) + { + return new SceneAnimationItem(path, ref id, typeName, AssetType); + } + /// public override Color AccentColor => Color.FromRGB(0xff5c4a87); diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index b5e5e2464..9dc0b1719 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -568,121 +568,12 @@ namespace FlaxEditor.SceneGraph.GUI { for (int i = 0; i < _dragAssets.Objects.Count; i++) { - var assetItem = _dragAssets.Objects[i]; - - if (assetItem.IsOfType()) - { - // Create actor - var model = FlaxEngine.Content.LoadAsync(assetItem.ID); - - var actor = new AnimatedModel - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - SkinnedModel = model, - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem.IsOfType()) - { - // Create actor - var model = FlaxEngine.Content.LoadAsync(assetItem.ID); - - var actor = new StaticModel - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - Model = model, - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem.IsOfType()) - { - // Create actor - var actor = new MeshCollider - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - CollisionData = FlaxEngine.Content.LoadAsync(assetItem.ID), - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem.IsOfType()) - { - // Create actor - var actor = new ParticleEffect - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - ParticleSystem = FlaxEngine.Content.LoadAsync(assetItem.ID), - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem.IsOfType()) - { - // Create actor - var actor = new SceneAnimationPlayer - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - Animation = FlaxEngine.Content.LoadAsync(assetItem.ID), - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem.IsOfType()) - { - // Create actor - var actor = new AudioSource - { - StaticFlags = Actor.StaticFlags, - Name = assetItem.ShortName, - Clip = FlaxEngine.Content.LoadAsync(assetItem.ID), - Transform = Actor.Transform - }; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - - break; - } - else if (assetItem.IsOfType()) - { - // Create prefab instance - var prefab = FlaxEngine.Content.LoadAsync(assetItem.ID); - var actor = PrefabManager.SpawnPrefab(prefab, null); - actor.StaticFlags = Actor.StaticFlags; - actor.Name = assetItem.ShortName; - actor.Transform = Actor.Transform; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } - else if (assetItem is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) - { - // Create actor - var actor = (Actor)visualScriptItem.ScriptType.CreateInstance(); - actor.StaticFlags = Actor.StaticFlags; - actor.Name = assetItem.ShortName; - actor.Transform = Actor.Transform; - - // Spawn - ActorNode.Root.Spawn(actor, Actor); - } + var item = _dragAssets.Objects[i]; + var actor = item.OnEditorDrop(this); + actor.StaticFlags = Actor.StaticFlags; + actor.Name = item.ShortName; + actor.Transform = Actor.Transform; + ActorNode.Root.Spawn(actor, Actor); } result = DragDropEffect.Move; @@ -737,46 +628,12 @@ namespace FlaxEditor.SceneGraph.GUI return actorNode.Actor != null && actorNode != ActorNode && actorNode.Find(Actor) == null; } - /// - /// Validates the asset for drag and drop into one of the scene tree nodes. - /// - /// The item. - /// True if can drag and drop it, otherwise false. - public static bool ValidateDragAsset(AssetItem assetItem) + private bool ValidateDragAsset(AssetItem assetItem) { - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem.IsOfType()) - return true; - - if (assetItem is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) - return true; - - return false; + return assetItem.OnEditorDrag(this); } - /// - /// Validates the type of the actor for drag and drop into one of the scene tree nodes. - /// - /// Type of the actor. - /// True if can drag and drop it, otherwise false. - public static bool ValidateDragActorType(ScriptType actorType) + private static bool ValidateDragActorType(ScriptType actorType) { return true; } diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs index 0c895640d..ea63a598b 100644 --- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs +++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs @@ -36,7 +36,7 @@ namespace FlaxEditor.Viewport private readonly ViewportWidgetButton _rotateSnapping; private readonly ViewportWidgetButton _scaleSnapping; - private readonly DragAssets _dragAssets = new DragAssets(ValidateDragItem); + private readonly DragAssets _dragAssets; private readonly DragActorType _dragActorType = new DragActorType(ValidateDragActorType); private SelectionOutline _customSelectionOutline; @@ -187,6 +187,7 @@ namespace FlaxEditor.Viewport : base(Object.New(), editor.Undo) { _editor = editor; + _dragAssets = new DragAssets(ValidateDragItem); // Prepare rendering task Task.ActorsSource = ActorsSources.Scenes; @@ -800,31 +801,19 @@ namespace FlaxEditor.Viewport return result; } - private static bool ValidateDragItem(ContentItem contentItem) + private bool ValidateDragItem(ContentItem contentItem) { if (!Level.IsAnySceneLoaded) return false; if (contentItem is AssetItem assetItem) { - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) + if (assetItem.OnEditorDrag(this)) return true; if (assetItem.IsOfType()) return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; if (assetItem.IsOfType()) return true; - if (assetItem is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) - return true; } return false; @@ -891,119 +880,40 @@ namespace FlaxEditor.Viewport private void Spawn(AssetItem item, SceneGraphNode hit, ref Vector2 location, ref Vector3 hitLocation) { - if (item is AssetItem assetItem) + if (item.IsOfType()) { - if (assetItem.IsOfType()) + if (hit is StaticModelNode staticModelNode) { - var asset = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new ParticleEffect - { - Name = item.ShortName, - ParticleSystem = asset - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - var asset = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new SceneAnimationPlayer - { - Name = item.ShortName, - Animation = asset - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - if (hit is StaticModelNode staticModelNode) - { - var staticModel = (StaticModel)staticModelNode.Actor; - var ray = ConvertMouseToRay(ref location); - if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex)) - { - var material = FlaxEngine.Content.LoadAsync(item.ID); - using (new UndoBlock(Undo, staticModel, "Change material")) - staticModel.SetMaterial(entryIndex, material); - } - } - else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode) + var staticModel = (StaticModel)staticModelNode.Actor; + var ray = ConvertMouseToRay(ref location); + if (staticModel.IntersectsEntry(ref ray, out _, out _, out var entryIndex)) { var material = FlaxEngine.Content.LoadAsync(item.ID); - using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material")) - { - var surface = brushSurfaceNode.Surface; - surface.Material = material; - brushSurfaceNode.Surface = surface; - } + using (new UndoBlock(Undo, staticModel, "Change material")) + staticModel.SetMaterial(entryIndex, material); } - return; } - if (assetItem.IsOfType()) + else if (hit is BoxBrushNode.SideLinkNode brushSurfaceNode) { - var model = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new AnimatedModel + var material = FlaxEngine.Content.LoadAsync(item.ID); + using (new UndoBlock(Undo, brushSurfaceNode.Brush, "Change material")) { - Name = item.ShortName, - SkinnedModel = model - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - var model = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new StaticModel - { - Name = item.ShortName, - Model = model - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - var collisionData = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new MeshCollider - { - Name = item.ShortName, - CollisionData = collisionData - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - var clip = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new AudioSource - { - Name = item.ShortName, - Clip = clip - }; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - var prefab = FlaxEngine.Content.LoadAsync(item.ID); - var actor = PrefabManager.SpawnPrefab(prefab, null); - actor.Name = item.ShortName; - Spawn(actor, ref hitLocation); - return; - } - if (assetItem.IsOfType()) - { - Editor.Instance.Scene.OpenScene(item.ID, true); - return; - } - if (assetItem is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) - { - var actor = (Actor)visualScriptItem.ScriptType.CreateInstance(); - actor.Name = item.ShortName; - Spawn(actor, ref hitLocation); - return; + var surface = brushSurfaceNode.Surface; + surface.Material = material; + brushSurfaceNode.Surface = surface; + } } + return; + } + if (item.IsOfType()) + { + Editor.Instance.Scene.OpenScene(item.ID, true); + return; + } + { + var actor = item.OnEditorDrop(this); + actor.Name = item.ShortName; + Spawn(actor, ref hitLocation); } } diff --git a/Source/Editor/Viewport/PrefabWindowViewport.cs b/Source/Editor/Viewport/PrefabWindowViewport.cs index 6483700b6..e189a8e62 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.Security.Policy; using FlaxEditor.Content; using FlaxEditor.Gizmo; using FlaxEditor.GUI.ContextMenu; @@ -53,7 +54,7 @@ namespace FlaxEditor.Viewport private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32); private IntPtr _debugDrawContext; private PrefabSpritesRenderer _spritesRenderer; - private readonly DragAssets _dragAssets = new DragAssets(ValidateDragItem); + private readonly DragAssets _dragAssets; private readonly DragActorType _dragActorType = new DragActorType(ValidateDragActorType); private readonly DragHandlers _dragHandlers = new DragHandlers(); @@ -89,6 +90,7 @@ namespace FlaxEditor.Viewport Undo = window.Undo; ViewportCamera = new FPSCamera(); _debugDrawContext = DebugDraw.AllocateContext(); + _dragAssets = new DragAssets(ValidateDragItem); // Prepare rendering task Task.ActorsSource = ActorsSources.CustomActors; @@ -673,24 +675,14 @@ namespace FlaxEditor.Viewport return _dragHandlers.OnDragEnter(data); } - private static bool ValidateDragItem(ContentItem contentItem) + private bool ValidateDragItem(ContentItem contentItem) { if (contentItem is AssetItem assetItem) { - if (assetItem.IsOfType()) + if (assetItem.OnEditorDrag(this)) return true; if (assetItem.IsOfType()) return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; - if (assetItem.IsOfType()) - return true; - if (assetItem is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) - return true; } return false; @@ -743,17 +735,6 @@ namespace FlaxEditor.Viewport { if (item is BinaryAssetItem binaryAssetItem) { - if (binaryAssetItem.Type == typeof(ParticleSystem)) - { - var particleSystem = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new ParticleEffect - { - Name = item.ShortName, - ParticleSystem = particleSystem - }; - Spawn(actor, ref hitLocation); - return; - } if (typeof(MaterialBase).IsAssignableFrom(binaryAssetItem.Type)) { if (hit is StaticModelNode staticModelNode) @@ -769,65 +750,11 @@ namespace FlaxEditor.Viewport } return; } - if (typeof(SkinnedModel).IsAssignableFrom(binaryAssetItem.Type)) - { - var model = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new AnimatedModel - { - Name = item.ShortName, - SkinnedModel = model - }; - Spawn(actor, ref hitLocation); - return; - } - if (typeof(Model).IsAssignableFrom(binaryAssetItem.Type)) - { - var model = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new StaticModel - { - Name = item.ShortName, - Model = model - }; - Spawn(actor, ref hitLocation); - return; - } - if (binaryAssetItem.IsOfType()) - { - var collisionData = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new MeshCollider - { - Name = item.ShortName, - CollisionData = collisionData - }; - Spawn(actor, ref hitLocation); - return; - } - if (typeof(AudioClip).IsAssignableFrom(binaryAssetItem.Type)) - { - var clip = FlaxEngine.Content.LoadAsync(item.ID); - var actor = new AudioSource - { - Name = item.ShortName, - Clip = clip - }; - Spawn(actor, ref hitLocation); - return; - } - if (typeof(Prefab).IsAssignableFrom(binaryAssetItem.Type)) - { - var prefab = FlaxEngine.Content.LoadAsync(item.ID); - var actor = PrefabManager.SpawnPrefab(prefab, null); - actor.Name = item.ShortName; - Spawn(actor, ref hitLocation); - return; - } } - if (item is VisualScriptItem visualScriptItem && new ScriptType(typeof(Actor)).IsAssignableFrom(visualScriptItem.ScriptType) && visualScriptItem.ScriptType.CanCreateInstance) { - var actor = (Actor)visualScriptItem.ScriptType.CreateInstance(); + var actor = item.OnEditorDrop(this); actor.Name = item.ShortName; Spawn(actor, ref hitLocation); - return; } }