diff --git a/Source/Editor/Gizmo/EditorPrimitives.cs b/Source/Editor/Gizmo/EditorPrimitives.cs
index bfc32a638..8172a5eb2 100644
--- a/Source/Editor/Gizmo/EditorPrimitives.cs
+++ b/Source/Editor/Gizmo/EditorPrimitives.cs
@@ -35,7 +35,7 @@ namespace FlaxEditor.Gizmo
///
public EditorPrimitives()
{
- Order = -100;
+ Order = 100;
}
///
diff --git a/Source/Editor/Gizmo/ViewportRubberBandSelector.cs b/Source/Editor/Gizmo/ViewportRubberBandSelector.cs
index 33caf5c8d..b9f458705 100644
--- a/Source/Editor/Gizmo/ViewportRubberBandSelector.cs
+++ b/Source/Editor/Gizmo/ViewportRubberBandSelector.cs
@@ -11,7 +11,7 @@ namespace FlaxEngine.Gizmo;
///
/// Class for adding viewport rubber band selection.
///
-public class ViewportRubberBandSelector
+public sealed class ViewportRubberBandSelector
{
private bool _isMosueCaptured;
private bool _isRubberBandSpanning;
@@ -232,30 +232,15 @@ public class ViewportRubberBandSelector
}
///
- /// Used to draw the rubber band. Begins render 2D.
+ /// Draws the ruber band during owner viewport UI drawing.
///
- /// The GPU Context.
- /// The GPU texture target.
- /// The GPU texture target depth.
- public void Draw(GPUContext context, GPUTexture target, GPUTexture targetDepth)
- {
- // Draw RubberBand for rect selection
- if (!_isRubberBandSpanning)
- return;
- Render2D.Begin(context, target, targetDepth);
- Draw2D();
- Render2D.End();
- }
-
- ///
- /// Used to draw the rubber band. Use if already rendering 2D context.
- ///
- public void Draw2D()
+ public void Draw()
{
if (!_isRubberBandSpanning)
return;
- Render2D.FillRectangle(_rubberBandRect, Style.Current.Selection);
- Render2D.DrawRectangle(_rubberBandRect, Style.Current.SelectionBorder);
+ var style = Style.Current;
+ Render2D.FillRectangle(_rubberBandRect, style.Selection);
+ Render2D.DrawRectangle(_rubberBandRect, style.SelectionBorder);
}
///
diff --git a/Source/Editor/SceneGraph/Actors/StaticModelNode.cs b/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
index b024c0287..2e212db64 100644
--- a/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
+++ b/Source/Editor/SceneGraph/Actors/StaticModelNode.cs
@@ -166,7 +166,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new BoxCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
- Transform = staticModelNode.Actor.Transform,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
createdNodes.Add(window is PrefabWindow pWindow ? pWindow.Graph.Root.Find(actor) : Editor.Instance.Scene.GetActorNode(actor));
@@ -177,7 +176,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new SphereCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
- Transform = staticModelNode.Actor.Transform,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
createdNodes.Add(window is PrefabWindow pWindow ? pWindow.Graph.Root.Find(actor) : Editor.Instance.Scene.GetActorNode(actor));
@@ -188,7 +186,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new BoxCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
- Transform = staticModelNode.Actor.Transform,
Size = new Float3(100.0f, 100.0f, 1.0f),
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
@@ -200,7 +197,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new CapsuleCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
- Transform = staticModelNode.Actor.Transform,
Radius = 25.0f,
Height = 50.0f,
};
@@ -217,7 +213,6 @@ namespace FlaxEditor.SceneGraph.Actors
var actor = new MeshCollider
{
StaticFlags = staticModelNode.Actor.StaticFlags,
- Transform = staticModelNode.Actor.Transform,
CollisionData = collisionData,
};
staticModelNode.Root.Spawn(actor, staticModelNode.Actor);
diff --git a/Source/Editor/Viewport/MainEditorGizmoViewport.cs b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
index c22cddb6a..ab1b8b312 100644
--- a/Source/Editor/Viewport/MainEditorGizmoViewport.cs
+++ b/Source/Editor/Viewport/MainEditorGizmoViewport.cs
@@ -371,9 +371,6 @@ namespace FlaxEditor.Viewport
Gizmos[i].Draw(ref renderContext);
}
- // Draw RubberBand for rect selection
- _rubberBandSelector.Draw(context, target, targetDepth);
-
// Draw selected objects debug shapes and visuals
if (DrawDebugDraw && (renderContext.View.Flags & ViewFlags.DebugDraw) == ViewFlags.DebugDraw)
{
@@ -589,6 +586,15 @@ namespace FlaxEditor.Viewport
}
}
+ ///
+ public override void Draw()
+ {
+ base.Draw();
+
+ // Draw rubber band for rectangle selection
+ _rubberBandSelector.Draw();
+ }
+
///
protected override void OrientViewport(ref Quaternion orientation)
{
diff --git a/Source/Engine/ContentImporters/ImportModel.cpp b/Source/Engine/ContentImporters/ImportModel.cpp
index 77cac2f03..c8777779b 100644
--- a/Source/Engine/ContentImporters/ImportModel.cpp
+++ b/Source/Engine/ContentImporters/ImportModel.cpp
@@ -24,6 +24,7 @@
#include "Engine/Level/Scripts/ModelPrefab.h"
#include "Engine/Platform/FileSystem.h"
#include "Engine/Utilities/RectPack.h"
+#include "Engine/Scripting/Scripting.h"
#include "Engine/Profiler/ProfilerCPU.h"
#include "AssetsImportingManager.h"
@@ -169,6 +170,33 @@ bool SortMeshGroups(IGrouping const& i1, IGroupingGetType().GetDefaultInstance();
+ src->Serialize(writer, defaultInstance);
+ writer.EndObject();
+
+ // Parse json
+ rapidjson_flax::Document document;
+ document.Parse(buffer.GetString(), buffer.GetSize());
+
+ // Strip unwanted data
+ document.RemoveMember("ID");
+ document.RemoveMember("ParentID");
+ document.RemoveMember("PrefabID");
+ document.RemoveMember("PrefabObjectID");
+ if (stripName)
+ document.RemoveMember("Name");
+
+ // Deserialize destination
+ auto modifier = Cache::ISerializeModifier.Get();
+ dst->Deserialize(document, &*modifier);
+}
+
CreateAssetResult ImportModel::Import(CreateAssetContext& context)
{
// Get import options
@@ -677,6 +705,8 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
// Create prefab structure
Dictionary nodeToActor;
+ Dictionary newPrefabObjects; // Maps prefab object id to the restored and linked object
+ rapidjson_flax::StringBuffer jsonBuffer;
Array nodeActors;
Actor* rootActor = nullptr;
for (int32 nodeIndex = 0; nodeIndex < data.Nodes.Count(); nodeIndex++)
@@ -767,7 +797,6 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
// Link with object from prefab (if reimporting)
if (prefab)
{
- rapidjson_flax::StringBuffer buffer;
for (Actor* a : nodeActors)
{
for (const auto& i : prefab->ObjectsCache)
@@ -779,33 +808,12 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
continue;
// Preserve local changes made in the prefab
- {
- // Serialize
- buffer.Clear();
- CompactJsonWriter writer(buffer);
- writer.StartObject();
- const void* defaultInstance = o->GetType().GetDefaultInstance();
- o->Serialize(writer, defaultInstance);
- writer.EndObject();
-
- // Parse json
- rapidjson_flax::Document document;
- document.Parse(buffer.GetString(), buffer.GetSize());
-
- // Strip unwanted data
- document.RemoveMember("ID");
- document.RemoveMember("ParentID");
- document.RemoveMember("PrefabID");
- document.RemoveMember("PrefabObjectID");
- document.RemoveMember("Name");
-
- // Deserialize object
- auto modifier = Cache::ISerializeModifier.Get();
- a->Deserialize(document, &*modifier);
- }
+ CloneObject(jsonBuffer, o, a, true);
// Mark as this object already exists in prefab so will be preserved when updating it
- a->LinkPrefab(o->GetPrefabID(), o->GetPrefabObjectID());
+ const Guid prefabObjectId = o->GetPrefabObjectID();
+ a->LinkPrefab(o->GetPrefabID(), prefabObjectId);
+ newPrefabObjects.Add(prefabObjectId, a);
break;
}
}
@@ -826,12 +834,43 @@ CreateAssetResult ImportModel::CreatePrefab(CreateAssetContext& context, ModelDa
{
if (i.Value->GetTypeHandle() == modelPrefabScript->GetTypeHandle())
{
- modelPrefabScript->LinkPrefab(i.Value->GetPrefabID(), i.Value->GetPrefabObjectID());
+ const Guid prefabObjectId = i.Value->GetPrefabObjectID();
+ modelPrefabScript->LinkPrefab(i.Value->GetPrefabID(), prefabObjectId);
+ newPrefabObjects.Add(prefabObjectId, modelPrefabScript);
break;
}
}
}
}
+ if (prefab)
+ {
+ // Preserve existing objects added by user (eg. colliders, sfx, vfx, scripts)
+ for (const auto& i : prefab->ObjectsCache)
+ {
+ // Skip already restored objects
+ const Guid prefabObjectId = i.Key;
+ if (newPrefabObjects.ContainsKey(prefabObjectId))
+ continue;
+ SceneObject* defaultObject = i.Value;
+ // TODO: ignore objects that were imported previously but not now (eg. mesh was removed from source asset)
+
+ // Find parent to link
+ SceneObject* parent;
+ if (!newPrefabObjects.TryGet(defaultObject->GetParent()->GetPrefabObjectID(), parent))
+ continue;
+
+ // Duplicate object
+ SceneObject* restoredObject = (SceneObject*)Scripting::NewObject(defaultObject->GetTypeHandle());
+ if (!restoredObject)
+ continue;
+ CloneObject(jsonBuffer, defaultObject, restoredObject);
+ restoredObject->SetParent((Actor*)parent);
+
+ // Link with existing prefab instance
+ restoredObject->LinkPrefab(i.Value->GetPrefabID(), prefabObjectId);
+ newPrefabObjects.Add(prefabObjectId, restoredObject);
+ }
+ }
// Create prefab instead of native asset
bool failed;