From ad8bec40bbab560775bb8019c70b5b5da112a170 Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Wed, 10 Apr 2024 05:04:36 -0400
Subject: [PATCH 1/7] Add creating particle systems from particle emitters.
---
.../Content/Proxy/ParticleEmitterProxy.cs | 56 +++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs b/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
index 8c1204128..9ac4d698c 100644
--- a/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
+++ b/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
@@ -3,6 +3,9 @@
using System;
using FlaxEditor.Content.Create;
using FlaxEditor.Content.Thumbnails;
+using FlaxEditor.GUI.ContextMenu;
+using FlaxEditor.GUI.Timeline;
+using FlaxEditor.GUI.Timeline.Tracks;
using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
@@ -48,6 +51,59 @@ namespace FlaxEditor.Content
Editor.Instance.ContentImporting.Create(new ParticleEmitterCreateEntry(outputPath));
}
+ ///
+ public override void OnContentWindowContextMenu(ContextMenu menu, ContentItem item)
+ {
+ base.OnContentWindowContextMenu(menu, item);
+
+ if (item is BinaryAssetItem binaryAssetItem)
+ {
+ var button = menu.AddButton("Create Particle System", CreateParticleSystemClicked);
+ button.Tag = binaryAssetItem;
+ }
+ }
+
+ private void CreateParticleSystemClicked(ContextMenuButton obj)
+ {
+ var binaryAssetItem = (BinaryAssetItem)obj.Tag;
+ CreateParticleSystem(binaryAssetItem);
+ }
+
+ ///
+ /// Creates the particle system from the given particle emitter.
+ ///
+ /// The particle emitter item to use as a base for the particle system.
+ public static void CreateParticleSystem(BinaryAssetItem emitterItem)
+ {
+ var particleSystemName = emitterItem.ShortName + " Particle System";
+ var particleSystemProxy = Editor.Instance.ContentDatabase.GetProxy();
+ Editor.Instance.Windows.ContentWin.NewItem(particleSystemProxy, null, item => OnParticleSystemCreated(item, emitterItem), particleSystemName);
+ }
+
+ private static void OnParticleSystemCreated(ContentItem item, BinaryAssetItem particleItem)
+ {
+ var assetItem = (AssetItem)item;
+ var particleSystem = FlaxEngine.Content.LoadAsync(assetItem.ID);
+ if (particleSystem == null || particleSystem.WaitForLoaded())
+ {
+ Editor.LogError("Failed to load created particle system.");
+ return;
+ }
+
+ ParticleEmitter emitter = FlaxEngine.Content.LoadAsync(particleItem.ID);
+
+ ParticleSystemPreview tempPreview = new ParticleSystemPreview(false);
+ ParticleSystemTimeline timeline = new ParticleSystemTimeline(tempPreview);
+ timeline.Load(particleSystem);
+
+ var track = (ParticleEmitterTrack)timeline.NewTrack(ParticleEmitterTrack.GetArchetype());
+ track.Asset = emitter;
+ track.TrackMedia.DurationFrames = timeline.DurationFrames;
+ track.Rename(particleItem.ShortName);
+ timeline.AddTrack(track);
+ timeline.Save(particleSystem);
+ }
+
///
public override void OnThumbnailDrawPrepare(ThumbnailRequest request)
{
From 48400ff5cea79ae637e602508def16e2830594b2 Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Wed, 10 Apr 2024 16:26:29 -0400
Subject: [PATCH 2/7] Add better error handling to particle system creation.
Add skinned model -> animation graph workflow, though a bit hacky.
---
.../Content/Proxy/ParticleEmitterProxy.cs | 4 ++
.../Editor/Content/Proxy/SkinnedModelProxy.cs | 55 +++++++++++++++++++
.../Windows/Assets/AnimationGraphWindow.cs | 9 +++
3 files changed, 68 insertions(+)
diff --git a/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs b/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
index 9ac4d698c..be2530efa 100644
--- a/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
+++ b/Source/Editor/Content/Proxy/ParticleEmitterProxy.cs
@@ -91,6 +91,10 @@ namespace FlaxEditor.Content
}
ParticleEmitter emitter = FlaxEngine.Content.LoadAsync(particleItem.ID);
+ if (emitter == null || emitter.WaitForLoaded())
+ {
+ Editor.LogError("Failed to load base particle emitter.");
+ }
ParticleSystemPreview tempPreview = new ParticleSystemPreview(false);
ParticleSystemTimeline timeline = new ParticleSystemTimeline(tempPreview);
diff --git a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
index e05ca80d9..97e423a2d 100644
--- a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
+++ b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
@@ -2,6 +2,10 @@
using System;
using FlaxEditor.Content.Thumbnails;
+using FlaxEditor.GUI.ContextMenu;
+using FlaxEditor.GUI.Docking;
+using FlaxEditor.Options;
+using FlaxEditor.Surface;
using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
@@ -39,6 +43,57 @@ namespace FlaxEditor.Content
///
public override Type AssetType => typeof(SkinnedModel);
+ ///
+ public override void OnContentWindowContextMenu(ContextMenu menu, ContentItem item)
+ {
+ base.OnContentWindowContextMenu(menu, item);
+
+ if (item is BinaryAssetItem binaryAssetItem)
+ {
+ var button = menu.AddButton("Create Animation Graph", CreateAnimationGraphClicked);
+ button.Tag = binaryAssetItem;
+ }
+ }
+
+ private void CreateAnimationGraphClicked(ContextMenuButton obj)
+ {
+ var binaryAssetItem = (BinaryAssetItem)obj.Tag;
+ CreateAnimationGraph(binaryAssetItem);
+ }
+
+ ///
+ /// Creates the animation graph from the given particle emitter.
+ ///
+ /// The skinned model item to use as the base model for the animation graph.
+ public static void CreateAnimationGraph(BinaryAssetItem skinnedModelItem)
+ {
+ var animationGraphName = skinnedModelItem.ShortName + " Graph";
+ var animationGraphProxy = Editor.Instance.ContentDatabase.GetProxy();
+ Editor.Instance.Windows.ContentWin.NewItem(animationGraphProxy, null, item => OnAnimationGraphCreated(item, skinnedModelItem), animationGraphName);
+ }
+
+ private static void OnAnimationGraphCreated(ContentItem item, BinaryAssetItem skinnedModelItem)
+ {
+ var skinnedModel = FlaxEngine.Content.LoadAsync(skinnedModelItem.ID);
+ if (skinnedModel == null || skinnedModel.WaitForLoaded())
+ {
+ Editor.LogError("Failed to load base skinned model.");
+ }
+
+ // Hack the animation graph window to modify the base model of the animation graph.
+ AnimationGraphWindow win = new AnimationGraphWindow(Editor.Instance, item as AssetItem);
+ win.Show();
+
+ // Ensure the window knows the asset is loaded so we can save it later.
+ win.Asset.WaitForLoaded();
+ win.Update(0); // Call Update() to refresh the loaded flag.
+
+ win.SetBaseModel(skinnedModel);
+ win.Surface.MarkAsEdited();
+ win.Save();
+ win.Close();
+ }
+
///
public override void OnThumbnailDrawPrepare(ThumbnailRequest request)
{
diff --git a/Source/Editor/Windows/Assets/AnimationGraphWindow.cs b/Source/Editor/Windows/Assets/AnimationGraphWindow.cs
index 9d65e5f7b..e75becf72 100644
--- a/Source/Editor/Windows/Assets/AnimationGraphWindow.cs
+++ b/Source/Editor/Windows/Assets/AnimationGraphWindow.cs
@@ -295,6 +295,15 @@ namespace FlaxEditor.Windows.Assets
base.SetParameter(index, value);
}
+ ///
+ /// Sets the base model of the animation graph this window is editing.
+ ///
+ /// The new base model.
+ public void SetBaseModel(SkinnedModel baseModel)
+ {
+ _properties.BaseModel = baseModel;
+ }
+
///
protected override void UnlinkItem()
{
From 873ac347d4b81fa1a65e7daeaf7dbe3588558ad5 Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Wed, 10 Apr 2024 16:30:39 -0400
Subject: [PATCH 3/7] Remove extra usings.
---
Source/Editor/Content/Proxy/SkinnedModelProxy.cs | 3 ---
1 file changed, 3 deletions(-)
diff --git a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
index 97e423a2d..163df87da 100644
--- a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
+++ b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
@@ -3,9 +3,6 @@
using System;
using FlaxEditor.Content.Thumbnails;
using FlaxEditor.GUI.ContextMenu;
-using FlaxEditor.GUI.Docking;
-using FlaxEditor.Options;
-using FlaxEditor.Surface;
using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
From 8ef38178e6e16e52c823275fd048c4bbd838752f Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Wed, 10 Apr 2024 18:13:27 -0400
Subject: [PATCH 4/7] Allow the user to pick prefab type upon creation of a
prefab.
---
.../Content/Create/PrefabCreateEntry.cs | 72 +++++++++++++++++++
Source/Editor/Content/Proxy/PrefabProxy.cs | 16 ++---
2 files changed, 76 insertions(+), 12 deletions(-)
create mode 100644 Source/Editor/Content/Create/PrefabCreateEntry.cs
diff --git a/Source/Editor/Content/Create/PrefabCreateEntry.cs b/Source/Editor/Content/Create/PrefabCreateEntry.cs
new file mode 100644
index 000000000..b307f09dd
--- /dev/null
+++ b/Source/Editor/Content/Create/PrefabCreateEntry.cs
@@ -0,0 +1,72 @@
+// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
+
+using System;
+using FlaxEditor.Scripting;
+using FlaxEngine;
+using Object = FlaxEngine.Object;
+
+namespace FlaxEditor.Content.Create
+{
+ ///
+ /// Visual Script asset creating handler. Allows to specify base class to inherit from.
+ ///
+ ///
+ public class PrefabCreateEntry : CreateFileEntry
+ {
+ ///
+ /// The create options.
+ ///
+ public class Options
+ {
+ ///
+ /// The root actor.
+ ///
+ [TypeReference(typeof(FlaxEngine.Actor), nameof(IsValid))]
+ [Tooltip("The actor type of the root of the new Prefab.")]
+ public Type RootActorType = typeof(EmptyActor);
+
+ private static bool IsValid(Type type)
+ {
+ return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType;
+ }
+ }
+
+ private readonly Options _options = new Options();
+
+ ///
+ public override object Settings => _options;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The result file url.
+ public PrefabCreateEntry(string resultUrl)
+ : base("Settings", resultUrl)
+ {
+ }
+
+ ///
+ public override bool Create()
+ {
+ if (_options.RootActorType == null)
+ _options.RootActorType = typeof(EmptyActor);
+
+ ScriptType actorType = new ScriptType(_options.RootActorType);
+
+ Actor actor = null;
+ try
+ {
+ actor = actorType.CreateInstance() as Actor;
+ Object.Destroy(actor, 20.0f);
+ }
+ catch (Exception ex)
+ {
+ Editor.LogError("Failed to create prefab with root actor type: " + actorType.Name);
+ Editor.LogWarning(ex);
+ return true;
+ }
+
+ return PrefabManager.CreatePrefab(actor, ResultUrl, true);
+ }
+ }
+}
diff --git a/Source/Editor/Content/Proxy/PrefabProxy.cs b/Source/Editor/Content/Proxy/PrefabProxy.cs
index 18860995e..a97b6232f 100644
--- a/Source/Editor/Content/Proxy/PrefabProxy.cs
+++ b/Source/Editor/Content/Proxy/PrefabProxy.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
+using FlaxEditor.Content.Create;
using FlaxEditor.Content.Thumbnails;
using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows;
@@ -76,30 +77,21 @@ namespace FlaxEditor.Content
///
public override void Create(string outputPath, object arg)
{
- bool resetTransform = false;
var transform = Transform.Identity;
if (!(arg is Actor actor))
{
- // Create default prefab root object
- actor = new EmptyActor
- {
- Name = "Root"
- };
-
- // Cleanup it after usage
- Object.Destroy(actor, 20.0f);
+ Editor.Instance.ContentImporting.Create(new PrefabCreateEntry(outputPath));
+ return;
}
else if (actor.Scene != null)
{
// Create prefab with identity transform so the actor instance on a level will have it customized
- resetTransform = true;
transform = actor.LocalTransform;
actor.LocalTransform = Transform.Identity;
}
PrefabManager.CreatePrefab(actor, outputPath, true);
- if (resetTransform)
- actor.LocalTransform = transform;
+ actor.LocalTransform = transform;
}
///
From fe6c254a2496889fce842e42cdcab864ba3e9600 Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Wed, 10 Apr 2024 18:47:01 -0400
Subject: [PATCH 5/7] Support displaying "Widget" instead of "Prefab" in the
type description.
---
Source/Editor/Content/Items/PrefabItem.cs | 26 +++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/Source/Editor/Content/Items/PrefabItem.cs b/Source/Editor/Content/Items/PrefabItem.cs
index a61e07e7c..6394ed52c 100644
--- a/Source/Editor/Content/Items/PrefabItem.cs
+++ b/Source/Editor/Content/Items/PrefabItem.cs
@@ -42,6 +42,32 @@ namespace FlaxEditor.Content
///
public override SpriteHandle DefaultThumbnail => SpriteHandle.Invalid;
+ private string _cachedTypeDescription = null;
+
+ ///
+ public override string TypeDescription
+ {
+ get
+ {
+ if (_cachedTypeDescription != null)
+ return _cachedTypeDescription;
+
+ Prefab prefab = FlaxEngine.Content.LoadAsync(ID);
+ if (prefab.WaitForLoaded(5000))
+ {
+ _cachedTypeDescription = "Prefab";
+ }
+
+ Actor root = prefab.GetDefaultInstance();
+ if (root is UIControl or UICanvas)
+ _cachedTypeDescription = "Widget";
+ else
+ _cachedTypeDescription = "Prefab";
+
+ return _cachedTypeDescription;
+ }
+ }
+
///
public override bool IsOfType(Type type)
{
From 019230f6d9077ec025a5c6a84cc5bf4d8a9013f3 Mon Sep 17 00:00:00 2001
From: Menotdan <32620310+Menotdan@users.noreply.github.com>
Date: Thu, 11 Apr 2024 00:03:04 -0400
Subject: [PATCH 6/7] Allow users to choose what type of widget they want to
create.
---
.../Content/Create/PrefabCreateEntry.cs | 111 +++++++++++++++++-
Source/Editor/Content/Proxy/PrefabProxy.cs | 14 +--
2 files changed, 112 insertions(+), 13 deletions(-)
diff --git a/Source/Editor/Content/Create/PrefabCreateEntry.cs b/Source/Editor/Content/Create/PrefabCreateEntry.cs
index b307f09dd..e207343a5 100644
--- a/Source/Editor/Content/Create/PrefabCreateEntry.cs
+++ b/Source/Editor/Content/Create/PrefabCreateEntry.cs
@@ -3,12 +3,13 @@
using System;
using FlaxEditor.Scripting;
using FlaxEngine;
+using FlaxEngine.GUI;
using Object = FlaxEngine.Object;
namespace FlaxEditor.Content.Create
{
///
- /// Visual Script asset creating handler. Allows to specify base class to inherit from.
+ /// Prefab asset creating handler. Allows to specify base actor to use as the root.
///
///
public class PrefabCreateEntry : CreateFileEntry
@@ -69,4 +70,112 @@ namespace FlaxEditor.Content.Create
return PrefabManager.CreatePrefab(actor, ResultUrl, true);
}
}
+
+ ///
+ /// Widget asset creating handler. Allows to specify base UIControl to use as the root.
+ ///
+ ///
+ public class WidgetCreateEntry : CreateFileEntry
+ {
+ ///
+ /// The create options.
+ ///
+ public class Options
+ {
+ ///
+ /// Which mode is used to initialize this widget.
+ ///
+ public enum WidgetMode
+ {
+ ///
+ /// Initialize the widget with a UICanvas.
+ ///
+ Canvas,
+
+ ///
+ /// Initialize the widget with a UIControl.
+ ///
+ Control
+ }
+
+ ///
+ /// The mode used to initialize the widget.
+ ///
+ [Tooltip("Whether to initialize the widget with a canvas or a control.")]
+ public WidgetMode WidgetInitializationMode = WidgetMode.Canvas;
+
+ bool ShowRoot => WidgetInitializationMode == WidgetMode.Control;
+
+ ///
+ /// The root control.
+ ///
+ [TypeReference(typeof(Control), nameof(IsValid))]
+ [Tooltip("The control type of the root of the new Widget's root control."), VisibleIf(nameof(ShowRoot))]
+ public Type RootControlType = typeof(Panel);
+
+ private static bool IsValid(Type type)
+ {
+ return (type.IsPublic || type.IsNestedPublic) && !type.IsAbstract && !type.IsGenericType;
+ }
+ }
+
+ private readonly Options _options = new Options();
+
+ ///
+ public override object Settings => _options;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The result file url.
+ public WidgetCreateEntry(string resultUrl)
+ : base("Settings", resultUrl)
+ {
+ }
+
+ ///
+ public override bool Create()
+ {
+ Actor actor = null;
+
+ if (_options.WidgetInitializationMode == Options.WidgetMode.Control)
+ {
+ if (_options.RootControlType == null)
+ _options.RootControlType = typeof(Control);
+
+ ScriptType controlType = new ScriptType(_options.RootControlType);
+
+ Control control = null;
+ try
+ {
+ control = controlType.CreateInstance() as Control;
+ }
+ catch (Exception ex)
+ {
+ Editor.LogError("Failed to create widget with root control type: " + controlType.Name);
+ Editor.LogWarning(ex);
+ return true;
+ }
+
+ UIControl newControl = new UIControl();
+ newControl.Control = control;
+
+ actor = newControl;
+ }
+ else if (_options.WidgetInitializationMode == Options.WidgetMode.Canvas)
+ {
+ actor = new UICanvas();
+ }
+
+ if (actor == null)
+ {
+ Editor.LogError("Failed to create widget. Final actor was null.");
+ return true;
+ }
+
+ Object.Destroy(actor, 20.0f);
+
+ return PrefabManager.CreatePrefab(actor, ResultUrl, true);
+ }
+ }
}
diff --git a/Source/Editor/Content/Proxy/PrefabProxy.cs b/Source/Editor/Content/Proxy/PrefabProxy.cs
index a97b6232f..fd4eefdf2 100644
--- a/Source/Editor/Content/Proxy/PrefabProxy.cs
+++ b/Source/Editor/Content/Proxy/PrefabProxy.cs
@@ -233,18 +233,8 @@ namespace FlaxEditor.Content
///
public override void Create(string outputPath, object arg)
{
- // Create prefab with UI Control
- var actor = new UIControl
- {
- Name = Path.GetFileNameWithoutExtension(outputPath),
- StaticFlags = StaticFlags.None,
- };
- actor.Control = new Button
- {
- Text = "Button",
- };
- PrefabManager.CreatePrefab(actor, outputPath, false);
- Object.Destroy(actor, 20.0f);
+ Editor.Instance.ContentImporting.Create(new WidgetCreateEntry(outputPath));
+ return;
}
}
}
From 4683262cf307f7f3459efa5324805eba8104d11f Mon Sep 17 00:00:00 2001
From: Wojtek Figat
Date: Wed, 11 Sep 2024 13:38:31 +0200
Subject: [PATCH 7/7] Small codestyle tweaks
#2415
---
.../Content/Create/PrefabCreateEntry.cs | 30 +++++++------------
Source/Editor/Content/Items/PrefabItem.cs | 24 +++++++--------
Source/Editor/Content/Proxy/PrefabProxy.cs | 7 +++--
.../Editor/Content/Proxy/SkinnedModelProxy.cs | 6 ++--
4 files changed, 29 insertions(+), 38 deletions(-)
diff --git a/Source/Editor/Content/Create/PrefabCreateEntry.cs b/Source/Editor/Content/Create/PrefabCreateEntry.cs
index e207343a5..06d0c94d4 100644
--- a/Source/Editor/Content/Create/PrefabCreateEntry.cs
+++ b/Source/Editor/Content/Create/PrefabCreateEntry.cs
@@ -49,12 +49,8 @@ namespace FlaxEditor.Content.Create
///
public override bool Create()
{
- if (_options.RootActorType == null)
- _options.RootActorType = typeof(EmptyActor);
-
- ScriptType actorType = new ScriptType(_options.RootActorType);
-
- Actor actor = null;
+ var actorType = new ScriptType(_options.RootActorType ?? typeof(EmptyActor));
+ Actor actor;
try
{
actor = actorType.CreateInstance() as Actor;
@@ -102,7 +98,7 @@ namespace FlaxEditor.Content.Create
/// The mode used to initialize the widget.
///
[Tooltip("Whether to initialize the widget with a canvas or a control.")]
- public WidgetMode WidgetInitializationMode = WidgetMode.Canvas;
+ public WidgetMode WidgetInitializationMode = WidgetMode.Control;
bool ShowRoot => WidgetInitializationMode == WidgetMode.Control;
@@ -111,7 +107,7 @@ namespace FlaxEditor.Content.Create
///
[TypeReference(typeof(Control), nameof(IsValid))]
[Tooltip("The control type of the root of the new Widget's root control."), VisibleIf(nameof(ShowRoot))]
- public Type RootControlType = typeof(Panel);
+ public Type RootControlType = typeof(Button);
private static bool IsValid(Type type)
{
@@ -140,12 +136,8 @@ namespace FlaxEditor.Content.Create
if (_options.WidgetInitializationMode == Options.WidgetMode.Control)
{
- if (_options.RootControlType == null)
- _options.RootControlType = typeof(Control);
-
- ScriptType controlType = new ScriptType(_options.RootControlType);
-
- Control control = null;
+ var controlType = new ScriptType(_options.RootControlType ?? typeof(Control));
+ Control control;
try
{
control = controlType.CreateInstance() as Control;
@@ -157,10 +149,11 @@ namespace FlaxEditor.Content.Create
return true;
}
- UIControl newControl = new UIControl();
- newControl.Control = control;
-
- actor = newControl;
+ actor = new UIControl
+ {
+ Control = control,
+ Name = controlType.Name
+ };
}
else if (_options.WidgetInitializationMode == Options.WidgetMode.Canvas)
{
@@ -172,7 +165,6 @@ namespace FlaxEditor.Content.Create
Editor.LogError("Failed to create widget. Final actor was null.");
return true;
}
-
Object.Destroy(actor, 20.0f);
return PrefabManager.CreatePrefab(actor, ResultUrl, true);
diff --git a/Source/Editor/Content/Items/PrefabItem.cs b/Source/Editor/Content/Items/PrefabItem.cs
index 6394ed52c..3638f274f 100644
--- a/Source/Editor/Content/Items/PrefabItem.cs
+++ b/Source/Editor/Content/Items/PrefabItem.cs
@@ -11,6 +11,8 @@ namespace FlaxEditor.Content
///
public sealed class PrefabItem : JsonAssetItem
{
+ private string _cachedTypeDescription = null;
+
///
/// Initializes a new instance of the class.
///
@@ -42,28 +44,22 @@ namespace FlaxEditor.Content
///
public override SpriteHandle DefaultThumbnail => SpriteHandle.Invalid;
- private string _cachedTypeDescription = null;
-
///
public override string TypeDescription
{
get
{
- if (_cachedTypeDescription != null)
- return _cachedTypeDescription;
-
- Prefab prefab = FlaxEngine.Content.LoadAsync(ID);
- if (prefab.WaitForLoaded(5000))
+ if (_cachedTypeDescription == null)
{
_cachedTypeDescription = "Prefab";
+ var prefab = FlaxEngine.Content.Load(ID);
+ if (prefab)
+ {
+ Actor root = prefab.GetDefaultInstance();
+ if (root is UIControl or UICanvas)
+ _cachedTypeDescription = "Widget";
+ }
}
-
- Actor root = prefab.GetDefaultInstance();
- if (root is UIControl or UICanvas)
- _cachedTypeDescription = "Widget";
- else
- _cachedTypeDescription = "Prefab";
-
return _cachedTypeDescription;
}
}
diff --git a/Source/Editor/Content/Proxy/PrefabProxy.cs b/Source/Editor/Content/Proxy/PrefabProxy.cs
index 5f5a782b8..27bece29c 100644
--- a/Source/Editor/Content/Proxy/PrefabProxy.cs
+++ b/Source/Editor/Content/Proxy/PrefabProxy.cs
@@ -1,7 +1,6 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
-using System.IO;
using FlaxEditor.Content.Create;
using FlaxEditor.Content.Thumbnails;
using FlaxEditor.Viewport.Previews;
@@ -9,7 +8,6 @@ using FlaxEditor.Windows;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
using FlaxEngine.GUI;
-using Object = FlaxEngine.Object;
namespace FlaxEditor.Content
{
@@ -87,6 +85,7 @@ namespace FlaxEditor.Content
///
public override void Create(string outputPath, object arg)
{
+ bool resetTransform = false;
var transform = Transform.Identity;
if (!(arg is Actor actor))
{
@@ -96,12 +95,14 @@ namespace FlaxEditor.Content
else if (actor.HasScene)
{
// Create prefab with identity transform so the actor instance on a level will have it customized
+ resetTransform = true;
transform = actor.LocalTransform;
actor.LocalTransform = Transform.Identity;
}
PrefabManager.CreatePrefab(actor, outputPath, true);
- actor.LocalTransform = transform;
+ if (resetTransform)
+ actor.LocalTransform = transform;
}
///
diff --git a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
index 163df87da..551dd1beb 100644
--- a/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
+++ b/Source/Editor/Content/Proxy/SkinnedModelProxy.cs
@@ -71,13 +71,15 @@ namespace FlaxEditor.Content
private static void OnAnimationGraphCreated(ContentItem item, BinaryAssetItem skinnedModelItem)
{
- var skinnedModel = FlaxEngine.Content.LoadAsync(skinnedModelItem.ID);
- if (skinnedModel == null || skinnedModel.WaitForLoaded())
+ var skinnedModel = FlaxEngine.Content.Load(skinnedModelItem.ID);
+ if (skinnedModel == null)
{
Editor.LogError("Failed to load base skinned model.");
+ return;
}
// Hack the animation graph window to modify the base model of the animation graph.
+ // TODO: implement it without window logic (load AnimGraphSurface and set AnimationGraphWindow.BaseModelId to model)
AnimationGraphWindow win = new AnimationGraphWindow(Editor.Instance, item as AssetItem);
win.Show();