Add nested prefabs editing buttons inside Prefab Window

#1595
This commit is contained in:
Wojtek Figat
2025-02-16 20:34:33 +01:00
parent 086ddc96bb
commit 25067959eb
4 changed files with 41 additions and 27 deletions

View File

@@ -68,12 +68,16 @@ namespace FlaxEditor.CustomEditors.Dedicated
// Use default prefab instance as a reference for the editor
Values.SetReferenceValue(prefabInstance);
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter)
// Display prefab UI (when displaying object inside Prefab Window then display only nested prefabs)
var prefabId = prefab.ID;
Editor.GetPrefabNestedObject(ref prefabId, ref prefabObjectId, out var nestedPrefabId, out var nestedPrefabObjectId);
var nestedPrefab = FlaxEngine.Content.Load<Prefab>(nestedPrefabId);
var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
if (Presenter == Editor.Instance.Windows.PropertiesWin.Presenter || nestedPrefab)
{
// Add some UI
var panel = layout.CustomContainer<UniformGridPanel>();
panel.CustomControl.Height = 20.0f;
panel.CustomControl.SlotsVertically = 1;
var targetPrefab = nestedPrefab ?? prefab;
panel.CustomControl.SlotsHorizontally = 3;
// Selecting actor prefab asset
@@ -81,17 +85,21 @@ namespace FlaxEditor.CustomEditors.Dedicated
selectPrefab.Button.Clicked += () =>
{
Editor.Instance.Windows.ContentWin.ClearItemsSearch();
Editor.Instance.Windows.ContentWin.Select(prefab);
Editor.Instance.Windows.ContentWin.Select(targetPrefab);
};
// Edit selected prefab asset
var editPrefab = panel.Button("Edit Prefab");
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(prefab.ID));
// Viewing changes applied to this actor
var viewChanges = panel.Button("View Changes");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
editPrefab.Button.Clicked += () => Editor.Instance.Windows.ContentWin.Open(Editor.Instance.ContentDatabase.FindAsset(targetPrefab.ID));
}
else
{
panel.CustomControl.SlotsHorizontally = 1;
}
// Viewing changes applied to this actor
var viewChanges = panel.Button("View Changes");
viewChanges.Button.Clicked += () => ViewChanges(viewChanges.Button, new Float2(0.0f, 20.0f));
// Link event to update editor on prefab apply
_linkedPrefabId = prefab.ID;

View File

@@ -501,7 +501,8 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
return false;
const ISerializable::DeserializeStream& newRootData = **newRootDataPtr;
Guid prefabId, prefabObjectID;
if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") && JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID"))
if (JsonTools::GetGuidIfValid(prefabId, newRootData, "PrefabID") &&
JsonTools::GetGuidIfValid(prefabObjectID, newRootData, "PrefabObjectID"))
{
const auto nestedPrefab = Content::Load<Prefab>(prefabId);
if (nestedPrefab && nestedPrefab->GetRootObjectId() != prefabObjectID)
@@ -511,21 +512,6 @@ DEFINE_INTERNAL_CALL(bool) EditorInternal_CanSetToRoot(Prefab* prefab, Actor* ta
return true;
}
DEFINE_INTERNAL_CALL(void) EditorInternal_GetPrefabNestedObject(Guid* prefabId, Guid* prefabObjectId, Guid* outPrefabId, Guid* outPrefabObjectId)
{
*outPrefabId = Guid::Empty;
*outPrefabObjectId = Guid::Empty;
const auto prefab = Content::Load<Prefab>(*prefabId);
if (!prefab)
return;
const ISerializable::DeserializeStream** prefabObjectDataPtr = prefab->ObjectsDataCache.TryGet(*prefabObjectId);
if (!prefabObjectDataPtr)
return;
const ISerializable::DeserializeStream& prefabObjectData = **prefabObjectDataPtr;
JsonTools::GetGuidIfValid(*outPrefabId, prefabObjectData, "PrefabID");
JsonTools::GetGuidIfValid(*outPrefabObjectId, prefabObjectData, "PrefabObjectID");
}
DEFINE_INTERNAL_CALL(float) EditorInternal_GetAnimationTime(AnimatedModel* animatedModel)
{
return animatedModel && animatedModel->GraphInstance.State.Count() == 1 ? animatedModel->GraphInstance.State[0].Animation.TimePosition : 0.0f;

View File

@@ -12,11 +12,14 @@
#include "Engine/Scripting/ManagedCLR/MException.h"
#include "Engine/Scripting/Internal/MainThreadManagedInvokeAction.h"
#include "Engine/Content/Assets/VisualScript.h"
#include "Engine/Content/Content.h"
#include "Engine/CSG/CSGBuilder.h"
#include "Engine/Engine/CommandLine.h"
#include "Engine/Renderer/ProbesRenderer.h"
#include "Engine/Animations/Graph/AnimGraph.h"
#include "Engine/Core/ObjectsRemovalService.h"
#include "Engine/Level/Prefabs/Prefab.h"
#include "Engine/Serialization/JsonTools.h"
ManagedEditor::InternalOptions ManagedEditor::ManagedEditorOptions;
@@ -592,6 +595,7 @@ bool ManagedEditor::EvaluateVisualScriptLocal(VisualScript* script, VisualScript
void ManagedEditor::WipeOutLeftoverSceneObjects()
{
PROFILE_CPU();
Array<ScriptingObject*> objects = Scripting::GetObjects();
bool removedAny = false;
for (ScriptingObject* object : objects)
@@ -613,6 +617,21 @@ void ManagedEditor::WipeOutLeftoverSceneObjects()
ObjectsRemovalService::Flush();
}
void ManagedEditor::GetPrefabNestedObject(const Guid& prefabId, const Guid& prefabObjectId, Guid& outPrefabId, Guid& outPrefabObjectId)
{
outPrefabId = Guid::Empty;
outPrefabObjectId = Guid::Empty;
const auto prefab = Content::Load<Prefab>(prefabId);
if (!prefab)
return;
const ISerializable::DeserializeStream** prefabObjectDataPtr = prefab->ObjectsDataCache.TryGet(prefabObjectId);
if (!prefabObjectDataPtr)
return;
const ISerializable::DeserializeStream& prefabObjectData = **prefabObjectDataPtr;
JsonTools::GetGuidIfValid(outPrefabId, prefabObjectData, "PrefabID");
JsonTools::GetGuidIfValid(outPrefabObjectId, prefabObjectData, "PrefabObjectID");
}
void ManagedEditor::OnEditorAssemblyLoaded(MAssembly* assembly)
{
ASSERT(!HasManagedInstance());

View File

@@ -259,6 +259,7 @@ public:
API_FUNCTION(Internal) static Array<VisualScriptLocal> GetVisualScriptLocals();
API_FUNCTION(Internal) static bool EvaluateVisualScriptLocal(VisualScript* script, API_PARAM(Ref) VisualScriptLocal& local);
API_FUNCTION(Internal) static void WipeOutLeftoverSceneObjects();
API_FUNCTION(Internal) static void GetPrefabNestedObject(API_PARAM(Ref) const Guid& prefabId, API_PARAM(Ref) const Guid& prefabObjectId, API_PARAM(Out) Guid& outPrefabId, API_PARAM(Out) Guid& outPrefabObjectId);
private:
void OnEditorAssemblyLoaded(MAssembly* assembly);