Merge branch 'missing_script_replacement' of https://github.com/Menotdan/FlaxEngine into Menotdan-missing_script_replacement
This commit is contained in:
@@ -1,6 +1,11 @@
|
|||||||
using FlaxEditor.CustomEditors.Editors;
|
using FlaxEditor.Actions;
|
||||||
|
using FlaxEditor.CustomEditors.Editors;
|
||||||
|
using FlaxEditor.GUI;
|
||||||
|
using FlaxEditor.GUI.ContextMenu;
|
||||||
|
using FlaxEditor.Scripting;
|
||||||
using FlaxEngine;
|
using FlaxEngine;
|
||||||
using FlaxEngine.GUI;
|
using FlaxEngine.GUI;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace FlaxEditor.CustomEditors.Dedicated;
|
namespace FlaxEditor.CustomEditors.Dedicated;
|
||||||
|
|
||||||
@@ -10,6 +15,11 @@ namespace FlaxEditor.CustomEditors.Dedicated;
|
|||||||
[CustomEditor(typeof(MissingScript)), DefaultEditor]
|
[CustomEditor(typeof(MissingScript)), DefaultEditor]
|
||||||
public class MissingScriptEditor : GenericEditor
|
public class MissingScriptEditor : GenericEditor
|
||||||
{
|
{
|
||||||
|
DropPanel _dropPanel;
|
||||||
|
Button _replaceScriptButton;
|
||||||
|
CheckBox _shouldReplaceAllCheckbox;
|
||||||
|
CustomEditor _propertiesEditor;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override void Initialize(LayoutElementsContainer layout)
|
public override void Initialize(LayoutElementsContainer layout)
|
||||||
{
|
{
|
||||||
@@ -18,9 +28,157 @@ public class MissingScriptEditor : GenericEditor
|
|||||||
base.Initialize(layout);
|
base.Initialize(layout);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
_dropPanel = dropPanel;
|
||||||
|
_dropPanel.HeaderTextColor = Color.OrangeRed;
|
||||||
|
|
||||||
dropPanel.HeaderTextColor = Color.OrangeRed;
|
Panel replaceScriptPanel = new Panel
|
||||||
|
{
|
||||||
|
Parent = _dropPanel,
|
||||||
|
Height = 64,
|
||||||
|
};
|
||||||
|
|
||||||
|
_replaceScriptButton = new Button
|
||||||
|
{
|
||||||
|
Text = "Replace Script",
|
||||||
|
AnchorPreset = AnchorPresets.TopCenter,
|
||||||
|
Width = 240,
|
||||||
|
Height = 24,
|
||||||
|
X = -120,
|
||||||
|
Y = 0,
|
||||||
|
Parent = replaceScriptPanel,
|
||||||
|
};
|
||||||
|
_replaceScriptButton.Clicked += OnReplaceScriptButtonClicked;
|
||||||
|
|
||||||
|
Label replaceAllLabel = new Label
|
||||||
|
{
|
||||||
|
Text = "Replace All of Same Type",
|
||||||
|
AnchorPreset = AnchorPresets.BottomCenter,
|
||||||
|
Y = -34,
|
||||||
|
Parent = replaceScriptPanel,
|
||||||
|
};
|
||||||
|
replaceAllLabel.X -= FlaxEngine.GUI.Style.Current.FontSmall.MeasureText(replaceAllLabel.Text).X;
|
||||||
|
|
||||||
|
_shouldReplaceAllCheckbox = new CheckBox
|
||||||
|
{
|
||||||
|
TooltipText = "Wether or not to apply this script change to all scripts missing the same type.",
|
||||||
|
AnchorPreset = AnchorPresets.BottomCenter,
|
||||||
|
Y = -34,
|
||||||
|
Parent = replaceScriptPanel,
|
||||||
|
};
|
||||||
|
|
||||||
|
float centerDifference = (_shouldReplaceAllCheckbox.Right - replaceAllLabel.Left) / 2;
|
||||||
|
replaceAllLabel.X += centerDifference;
|
||||||
|
_shouldReplaceAllCheckbox.X += centerDifference;
|
||||||
|
|
||||||
base.Initialize(layout);
|
base.Initialize(layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<MissingScript> FindActorsWithMatchingMissingScript()
|
||||||
|
{
|
||||||
|
List<MissingScript> missingScripts = new List<MissingScript>();
|
||||||
|
|
||||||
|
foreach (Actor actor in Level.GetActors<Actor>())
|
||||||
|
{
|
||||||
|
for (int scriptIndex = 0; scriptIndex < actor.ScriptsCount; scriptIndex++)
|
||||||
|
{
|
||||||
|
Script actorScript = actor.Scripts[scriptIndex];
|
||||||
|
if (actorScript is not MissingScript missingActorScript)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MissingScript currentMissing = Values[0] as MissingScript;
|
||||||
|
if (missingActorScript.MissingTypeName != currentMissing.MissingTypeName)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Matching MissingScript.
|
||||||
|
missingScripts.Add(missingActorScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return missingScripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RunReplacementMulticast(List<IUndoAction> actions)
|
||||||
|
{
|
||||||
|
if (actions.Count == 0)
|
||||||
|
{
|
||||||
|
Editor.LogWarning("Failed to replace scripts!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var multiAction = new MultiUndoAction(actions);
|
||||||
|
multiAction.Do();
|
||||||
|
var presenter = ParentEditor.Presenter;
|
||||||
|
if (presenter != null)
|
||||||
|
{
|
||||||
|
presenter.Undo.AddAction(multiAction);
|
||||||
|
presenter.Control.Focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ReplaceScript(ScriptType script, bool replaceAllInScene)
|
||||||
|
{
|
||||||
|
var actions = new List<IUndoAction>(4);
|
||||||
|
|
||||||
|
List<MissingScript> missingScripts = new List<MissingScript>();
|
||||||
|
if (!replaceAllInScene)
|
||||||
|
{
|
||||||
|
missingScripts.Add(Values[0] as MissingScript);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
missingScripts = FindActorsWithMatchingMissingScript();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (MissingScript missingScript in missingScripts)
|
||||||
|
{
|
||||||
|
AddRemoveScript addReplacementScriptAction = AddRemoveScript.Add(missingScript.Actor, script);
|
||||||
|
actions.Add(addReplacementScriptAction);
|
||||||
|
}
|
||||||
|
RunReplacementMulticast(actions);
|
||||||
|
|
||||||
|
for (int actionIdx = 0; actionIdx < actions.Count; actionIdx++)
|
||||||
|
{
|
||||||
|
AddRemoveScript addRemoveScriptAction = (AddRemoveScript) actions[actionIdx];
|
||||||
|
int orderInParent = addRemoveScriptAction.GetOrderInParent();
|
||||||
|
|
||||||
|
Script newScript = missingScripts[actionIdx].Actor.Scripts[orderInParent];
|
||||||
|
missingScripts[actionIdx].ReferenceScript = newScript;
|
||||||
|
}
|
||||||
|
actions.Clear();
|
||||||
|
|
||||||
|
foreach (MissingScript missingScript in missingScripts)
|
||||||
|
{
|
||||||
|
actions.Add(AddRemoveScript.Remove(missingScript));
|
||||||
|
}
|
||||||
|
RunReplacementMulticast(actions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnReplaceScriptButtonClicked()
|
||||||
|
{
|
||||||
|
var scripts = Editor.Instance.CodeEditing.Scripts.Get();
|
||||||
|
if (scripts.Count == 0)
|
||||||
|
{
|
||||||
|
// No scripts
|
||||||
|
var cm1 = new ContextMenu();
|
||||||
|
cm1.AddButton("No scripts in project");
|
||||||
|
cm1.Show(_dropPanel, _replaceScriptButton.BottomLeft);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show context menu with list of scripts to add
|
||||||
|
var cm = new ItemsListContextMenu(180);
|
||||||
|
for (int i = 0; i < scripts.Count; i++)
|
||||||
|
{
|
||||||
|
cm.AddItem(new TypeSearchPopup.TypeItemView(scripts[i]));
|
||||||
|
}
|
||||||
|
// Get the parent (actor properties editor) of the parent (Scripts Editor) of our editor.
|
||||||
|
_propertiesEditor = ParentEditor.ParentEditor;
|
||||||
|
|
||||||
|
cm.ItemClicked += item => ReplaceScript((ScriptType)item.Tag, _shouldReplaceAllCheckbox.Checked);
|
||||||
|
cm.SortItems();
|
||||||
|
cm.Show(_dropPanel, _replaceScriptButton.BottomLeft - new Float2((cm.Width - _replaceScriptButton.Width) / 2, 0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,11 @@ namespace FlaxEditor.Actions
|
|||||||
_enabled = true;
|
_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int GetOrderInParent()
|
||||||
|
{
|
||||||
|
return _orderInParent;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new added script undo action.
|
/// Creates a new added script undo action.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -184,6 +189,7 @@ namespace FlaxEditor.Actions
|
|||||||
script.Parent = parentActor;
|
script.Parent = parentActor;
|
||||||
if (_orderInParent != -1)
|
if (_orderInParent != -1)
|
||||||
script.OrderInParent = _orderInParent;
|
script.OrderInParent = _orderInParent;
|
||||||
|
_orderInParent = script.OrderInParent; // Ensure _orderInParent is correct for script that want to use it.
|
||||||
if (_prefabObjectId != Guid.Empty)
|
if (_prefabObjectId != Guid.Empty)
|
||||||
SceneObject.Internal_LinkPrefab(Object.GetUnmanagedPtr(script), ref _prefabId, ref _prefabObjectId);
|
SceneObject.Internal_LinkPrefab(Object.GetUnmanagedPtr(script), ref _prefabId, ref _prefabObjectId);
|
||||||
Editor.Instance.Scene.MarkSceneEdited(parentActor.Scene);
|
Editor.Instance.Scene.MarkSceneEdited(parentActor.Scene);
|
||||||
|
|||||||
Reference in New Issue
Block a user