@@ -37,11 +37,6 @@ namespace FlaxEditor.Modules
|
||||
/// </summary>
|
||||
public event Action<Prefab, Actor> PrefabApplied;
|
||||
|
||||
/// <summary>
|
||||
/// Locally cached actor for prefab creation.
|
||||
/// </summary>
|
||||
private Actor _prefabCreationActor;
|
||||
|
||||
internal PrefabsModule(Editor editor)
|
||||
: base(editor)
|
||||
{
|
||||
@@ -65,13 +60,14 @@ namespace FlaxEditor.Modules
|
||||
/// To create prefab manually (from code) use <see cref="PrefabManager.CreatePrefab"/> method.
|
||||
/// </remarks>
|
||||
/// <param name="selection">The scene selection to use.</param>
|
||||
public void CreatePrefab(List<SceneGraphNode> selection)
|
||||
/// <param name="prefabWindow">The prefab window that creates it.</param>
|
||||
public void CreatePrefab(List<SceneGraphNode> selection, Windows.Assets.PrefabWindow prefabWindow = null)
|
||||
{
|
||||
if (selection == null)
|
||||
selection = Editor.SceneEditing.Selection;
|
||||
if (selection.Count == 1 && selection[0] is ActorNode actorNode && actorNode.CanCreatePrefab)
|
||||
{
|
||||
CreatePrefab(actorNode.Actor);
|
||||
CreatePrefab(actorNode.Actor, true, prefabWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +88,8 @@ namespace FlaxEditor.Modules
|
||||
/// </summary>
|
||||
/// <param name="actor">The root prefab actor.</param>
|
||||
/// <param name="rename">Allow renaming or not</param>
|
||||
public void CreatePrefab(Actor actor, bool rename)
|
||||
/// <param name="prefabWindow">The prefab window that creates it.</param>
|
||||
public void CreatePrefab(Actor actor, bool rename, Windows.Assets.PrefabWindow prefabWindow = null)
|
||||
{
|
||||
// Skip in invalid states
|
||||
if (!Editor.StateMachine.CurrentState.CanEditContent)
|
||||
@@ -105,42 +102,47 @@ namespace FlaxEditor.Modules
|
||||
PrefabCreating?.Invoke(actor);
|
||||
|
||||
var proxy = Editor.ContentDatabase.GetProxy<Prefab>();
|
||||
_prefabCreationActor = actor;
|
||||
Editor.Windows.ContentWin.NewItem(proxy, actor, OnPrefabCreated, actor.Name, rename);
|
||||
Editor.Windows.ContentWin.NewItem(proxy, actor, contentItem => OnPrefabCreated(contentItem, actor, prefabWindow), actor.Name, rename);
|
||||
}
|
||||
|
||||
private void OnPrefabCreated(ContentItem contentItem)
|
||||
private void OnPrefabCreated(ContentItem contentItem, Actor actor, Windows.Assets.PrefabWindow prefabWindow)
|
||||
{
|
||||
if (contentItem is PrefabItem prefabItem)
|
||||
{
|
||||
PrefabCreated?.Invoke(prefabItem);
|
||||
}
|
||||
|
||||
// Skip in invalid states
|
||||
if (!Editor.StateMachine.CurrentState.CanEditScene)
|
||||
return;
|
||||
Undo undo = null;
|
||||
if (prefabWindow != null)
|
||||
{
|
||||
prefabWindow.MarkAsEdited();
|
||||
undo = prefabWindow.Undo;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip in invalid states
|
||||
if (!Editor.StateMachine.CurrentState.CanEditScene)
|
||||
return;
|
||||
undo = Editor.Undo;
|
||||
}
|
||||
|
||||
// Record undo for prefab creating (backend links the target instance with the prefab)
|
||||
if (Editor.Undo.Enabled)
|
||||
if (undo.Enabled)
|
||||
{
|
||||
if (!_prefabCreationActor)
|
||||
if (!actor)
|
||||
return;
|
||||
|
||||
var actorsList = new List<Actor>();
|
||||
Utilities.Utils.GetActorsTree(actorsList, _prefabCreationActor);
|
||||
Utilities.Utils.GetActorsTree(actorsList, actor);
|
||||
|
||||
var actions = new IUndoAction[actorsList.Count];
|
||||
for (int i = 0; i < actorsList.Count; i++)
|
||||
{
|
||||
var action = BreakPrefabLinkAction.Linked(actorsList[i]);
|
||||
actions[i] = action;
|
||||
}
|
||||
Undo.AddAction(new MultiUndoAction(actions));
|
||||
|
||||
_prefabCreationActor = null;
|
||||
actions[i] = BreakPrefabLinkAction.Linked(actorsList[i]);
|
||||
undo.AddAction(new MultiUndoAction(actions));
|
||||
}
|
||||
|
||||
Editor.Instance.Windows.PropertiesWin.Presenter.BuildLayout();
|
||||
Editor.Windows.PropertiesWin.Presenter.BuildLayout();
|
||||
if (prefabWindow != null)
|
||||
prefabWindow.Presenter.BuildLayout();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -233,7 +233,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
|
||||
contextMenu.AddSeparator();
|
||||
|
||||
b = contextMenu.AddButton("Create Prefab", () => Editor.Prefabs.CreatePrefab(Selection));
|
||||
b = contextMenu.AddButton("Create Prefab", () => Editor.Prefabs.CreatePrefab(Selection, this));
|
||||
b.Enabled = isSingleActorSelected &&
|
||||
(Selection[0] as ActorNode).CanCreatePrefab &&
|
||||
Editor.Windows.ContentWin.CurrentViewFolder.CanHaveAssets;
|
||||
|
||||
@@ -53,6 +53,11 @@ namespace FlaxEditor.Windows.Assets
|
||||
/// </summary>
|
||||
public PrefabWindowViewport Viewport => _viewport;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the prefab objects properties editor.
|
||||
/// </summary>
|
||||
public CustomEditorPresenter Presenter => _propertiesEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the undo system used by this window for changes tracking.
|
||||
/// </summary>
|
||||
|
||||
@@ -321,6 +321,8 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat
|
||||
// Serialize to json data
|
||||
ASSERT(!IsCreatingPrefab);
|
||||
IsCreatingPrefab = true;
|
||||
const Guid targetPrefabId = targetActor->GetPrefabID();
|
||||
const bool hasTargetPrefabId = targetPrefabId.IsValid();
|
||||
rapidjson_flax::StringBuffer actorsDataBuffer;
|
||||
{
|
||||
CompactJsonWriter writerObj(actorsDataBuffer);
|
||||
@@ -329,7 +331,27 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat
|
||||
for (int32 i = 0; i < sceneObjects->Count(); i++)
|
||||
{
|
||||
SceneObject* obj = sceneObjects->At(i);
|
||||
|
||||
// Detect when creating prefab from object that is already part of prefab then serialize it as unlinked
|
||||
const Guid prefabId = obj->GetPrefabID();
|
||||
const Guid prefabObjectId = obj->GetPrefabObjectID();
|
||||
bool isObjectFromPrefab = targetPrefabId == prefabId && prefabId.IsValid(); // Allow to use other nested prefabs properly (ignore only root object's prefab link)
|
||||
if (isObjectFromPrefab)
|
||||
{
|
||||
//obj->BreakPrefabLink();
|
||||
obj->_prefabID = Guid::Empty;
|
||||
obj->_prefabObjectID = Guid::Empty;
|
||||
}
|
||||
|
||||
writer.SceneObject(obj);
|
||||
|
||||
// Restore broken link
|
||||
if (hasTargetPrefabId)
|
||||
{
|
||||
//obj->LinkPrefab(prefabId, prefabObjectId);
|
||||
obj->_prefabID = prefabId;
|
||||
obj->_prefabObjectID = prefabObjectId;
|
||||
}
|
||||
}
|
||||
writer.EndArray();
|
||||
}
|
||||
@@ -395,7 +417,6 @@ bool PrefabManager::CreatePrefab(Actor* targetActor, const StringView& outputPat
|
||||
{
|
||||
SceneObject* obj = sceneObjects->At(i);
|
||||
Guid prefabObjectId;
|
||||
|
||||
if (objectInstanceIdToPrefabObjectId.TryGet(obj->GetSceneObjectId(), prefabObjectId))
|
||||
{
|
||||
obj->LinkPrefab(assetInfo.ID, prefabObjectId);
|
||||
|
||||
@@ -81,7 +81,6 @@ void JsonTools::ChangeIds(Document& doc, const Dictionary<Guid, Guid>& mapping)
|
||||
::ChangeIds(doc, doc, mapping);
|
||||
}
|
||||
|
||||
|
||||
Float2 JsonTools::GetFloat2(const Value& value)
|
||||
{
|
||||
Float2 result;
|
||||
|
||||
Reference in New Issue
Block a user