Merge branch 'FlaxEngine:master' into add_spline_edit_options
This commit is contained in:
@@ -16,6 +16,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
/// <inheritdoc />
|
||||
protected override OptionType[] Options => new[]
|
||||
{
|
||||
new OptionType("null", null),
|
||||
new OptionType("Texture", typeof(TextureBrush)),
|
||||
new OptionType("Sprite", typeof(SpriteBrush)),
|
||||
new OptionType("GPU Texture", typeof(GPUTextureBrush)),
|
||||
|
||||
@@ -158,7 +158,9 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
if (comboBox.SelectedIndex != -1)
|
||||
{
|
||||
var option = _options[comboBox.SelectedIndex];
|
||||
value = option.Creator(option.Type);
|
||||
if (option.Type != null)
|
||||
value = option.Creator(option.Type);
|
||||
|
||||
}
|
||||
SetValue(value);
|
||||
RebuildLayoutOnRefresh();
|
||||
|
||||
@@ -42,6 +42,10 @@ public class Editor : EditorModule
|
||||
options.ScriptingAPI.SystemReferences.Add("System.Text.RegularExpressions");
|
||||
options.ScriptingAPI.SystemReferences.Add("System.ComponentModel.TypeConverter");
|
||||
|
||||
// Enable optimizations for Editor, disable this for debugging the editor
|
||||
if (options.Configuration == TargetConfiguration.Development)
|
||||
options.ScriptingAPI.Optimization = true;
|
||||
|
||||
options.PublicDependencies.Add("Engine");
|
||||
options.PrivateDependencies.Add("pugixml");
|
||||
options.PrivateDependencies.Add("curl");
|
||||
|
||||
@@ -1579,7 +1579,7 @@ namespace FlaxEditor
|
||||
private static void RequestStartPlayOnEditMode()
|
||||
{
|
||||
if (Instance.StateMachine.IsEditMode)
|
||||
Instance.Simulation.RequestStartPlay();
|
||||
Instance.Simulation.RequestStartPlayScenes();
|
||||
if (Instance.StateMachine.IsPlayMode)
|
||||
Instance.StateMachine.StateChanged -= RequestStartPlayOnEditMode;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
|
||||
private List<ContextMenu> _menus = new List<ContextMenu>();
|
||||
private List<SingleSelectGroupItem> _items = new List<SingleSelectGroupItem>();
|
||||
private bool _hasSelected = false;
|
||||
private SingleSelectGroupItem _selectedItem;
|
||||
|
||||
public T Selected
|
||||
@@ -31,7 +32,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
set
|
||||
{
|
||||
var index = _items.FindIndex(x => x.Value.Equals(value));
|
||||
if (index != -1 && !_selectedItem.Value.Equals(value))
|
||||
if (index != -1 && (!_hasSelected || !_selectedItem.Value.Equals(value)))
|
||||
{
|
||||
SetSelected(_items[index]);
|
||||
}
|
||||
@@ -70,7 +71,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
if (item.Tooltip != null)
|
||||
btn.TooltipText = item.Tooltip;
|
||||
item.Buttons.Add(btn);
|
||||
if (item.Equals(_selectedItem))
|
||||
if (_hasSelected && item.Equals(_selectedItem))
|
||||
btn.Checked = true;
|
||||
}
|
||||
|
||||
@@ -82,6 +83,7 @@ namespace FlaxEditor.GUI.ContextMenu
|
||||
btn.Checked = false;
|
||||
}
|
||||
_selectedItem = item;
|
||||
_hasSelected = true;
|
||||
|
||||
SelectedChanged?.Invoke(item.Value);
|
||||
item.Selected?.Invoke();
|
||||
|
||||
@@ -253,6 +253,12 @@ namespace FlaxEditor.GUI.Docking
|
||||
tabColor = style.BackgroundHighlighted;
|
||||
Render2D.FillRectangle(tabRect, tabColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
tabColor = style.BackgroundHighlighted;
|
||||
Render2D.DrawLine(tabRect.BottomLeft - new Float2(0 , 1), tabRect.UpperLeft, tabColor);
|
||||
Render2D.DrawLine(tabRect.BottomRight - new Float2(0 , 1), tabRect.UpperRight, tabColor);
|
||||
}
|
||||
|
||||
if (tab.Icon.IsValid)
|
||||
{
|
||||
|
||||
@@ -282,7 +282,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
var x = time * zoom + Timeline.StartOffset;
|
||||
|
||||
// Header line
|
||||
var lineRect = new Rectangle(x - 0.5f, -verticalLinesHeaderExtend + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend);
|
||||
var lineRect = new Rectangle(x - 0.5f, -verticalLinesHeaderExtend * 0.6f + timeAxisHeaderOffset, 1.0f, verticalLinesHeaderExtend * 0.6f);
|
||||
Render2D.FillRectangle(lineRect, lineColor);
|
||||
|
||||
// Time label
|
||||
@@ -300,7 +300,7 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
var labelRect = new Rectangle(x + 2, -verticalLinesHeaderExtend + timeAxisHeaderOffset, 50, verticalLinesHeaderExtend);
|
||||
var labelRect = new Rectangle(x + 2, -verticalLinesHeaderExtend * 0.8f + timeAxisHeaderOffset, 50, verticalLinesHeaderExtend);
|
||||
Render2D.DrawText(style.FontSmall, labelText, labelRect, labelColor, TextAlignment.Near, TextAlignment.Center, TextWrapping.NoWrap, 1.0f, 0.8f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
@@ -30,11 +32,33 @@ namespace FlaxEditor.GUI.Timeline.GUI
|
||||
var timeAxisOverlap = Timeline.HeaderTopAreaHeight * 0.5f;
|
||||
var timeAxisHeaderOffset = -_timeline.MediaBackground.ViewOffset.Y - timeAxisOverlap;
|
||||
|
||||
// Time label
|
||||
string labelText;
|
||||
switch (_timeline.TimeShowMode)
|
||||
{
|
||||
case Timeline.TimeShowModes.Frames:
|
||||
labelText = _timeline.CurrentFrame.ToString("###0", CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Timeline.TimeShowModes.Seconds:
|
||||
labelText = _timeline.CurrentTime.ToString("###0.##'s'", CultureInfo.InvariantCulture);
|
||||
break;
|
||||
case Timeline.TimeShowModes.Time:
|
||||
labelText = TimeSpan.FromSeconds(_timeline.CurrentTime).ToString("g");
|
||||
break;
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
var color = (_timeline.IsMovingPositionHandle ? style.ProgressNormal : style.Foreground).AlphaMultiplied(0.6f);
|
||||
Matrix3x3.RotationZ(Mathf.PiOverTwo, out var m1);
|
||||
var m2 = Matrix3x3.Translation2D(0, timeAxisHeaderOffset);
|
||||
Matrix3x3.Multiply(ref m1, ref m2, out var m3);
|
||||
Render2D.PushTransform(ref m3);
|
||||
Render2D.DrawSprite(icon, new Rectangle(new Float2(4, -Width), Size), _timeline.IsMovingPositionHandle ? style.ProgressNormal : style.Foreground);
|
||||
// TODO: Convert to its own sprite or 9 slice
|
||||
Render2D.DrawSprite(icon, new Rectangle(new Float2(10, -icon.Size.X * 0.5f - 1), Size + new Float2(0, 1)), color);
|
||||
Render2D.FillRectangle(new Rectangle(new Float2(-6, -icon.Size.Y * 0.5f + 7), new Float2(timeAxisOverlap, 5)), color);
|
||||
Render2D.PopTransform();
|
||||
var textMatrix = Matrix3x3.Translation2D(12, timeAxisHeaderOffset);
|
||||
Render2D.PushTransform(ref textMatrix);
|
||||
Render2D.DrawText(style.FontSmall, labelText, style.Foreground, new Float2(2, -6));
|
||||
Render2D.PopTransform();
|
||||
|
||||
Render2D.FillRectangle(new Rectangle(Width * 0.5f, Height + timeAxisHeaderOffset, 1, _timeline.MediaPanel.Height - timeAxisHeaderOffset - timeAxisOverlap), _timeline.IsMovingPositionHandle ? style.ProgressNormal : style.Foreground.RGBMultiplied(0.8f));
|
||||
|
||||
@@ -50,6 +50,27 @@ namespace FlaxEditor.GUI.Timeline
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseEnter(Float2 location)
|
||||
{
|
||||
base.OnMouseEnter(location);
|
||||
Cursor = CursorType.Hand;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnMouseLeave()
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
base.OnMouseLeave();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Defocus()
|
||||
{
|
||||
Cursor = CursorType.Default;
|
||||
base.Defocus();
|
||||
}
|
||||
|
||||
private void Seek(ref Float2 location)
|
||||
{
|
||||
if (_timeline.PlaybackState == PlaybackStates.Disabled)
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace FlaxEditor.GUI.Timeline
|
||||
/// <summary>
|
||||
/// The header top area height (in pixels).
|
||||
/// </summary>
|
||||
public static readonly float HeaderTopAreaHeight = 22.0f;
|
||||
public static readonly float HeaderTopAreaHeight = 40.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The timeline units per second (on time axis).
|
||||
|
||||
@@ -298,7 +298,7 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
var animEventTypes = Editor.Instance.CodeEditing.All.Get().Where(x => new ScriptType(typeof(AnimEvent)).IsAssignableFrom(x));
|
||||
foreach (var type in animEventTypes)
|
||||
{
|
||||
if (type.IsAbstract || !type.CanCreateInstance)
|
||||
if (type.IsAbstract || !type.CanCreateInstance || type.HasAttribute(typeof(HideInEditorAttribute), true))
|
||||
continue;
|
||||
var add = new ScriptType(typeof(AnimContinuousEvent)).IsAssignableFrom(type) ? addContinuousEvent : addEvent;
|
||||
var b = add.ContextMenu.AddButton(type.Name);
|
||||
@@ -307,6 +307,10 @@ namespace FlaxEditor.GUI.Timeline.Tracks
|
||||
b.Parent.Tag = time;
|
||||
b.ButtonClicked += OnAddAnimEvent;
|
||||
}
|
||||
if (!addEvent.ContextMenu.Items.Any())
|
||||
addEvent.ContextMenu.AddButton("No Anim Events found").CloseMenuOnClick = false;
|
||||
if (!addContinuousEvent.ContextMenu.Items.Any())
|
||||
addContinuousEvent.ContextMenu.AddButton("No Continuous Anim Events found").CloseMenuOnClick = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -503,7 +503,7 @@ namespace FlaxEditor.Modules
|
||||
// Set paste target if only one actor is selected and no target provided
|
||||
if (pasteTargetActor == null && SelectionCount == 1 && Selection[0] is ActorNode actorNode)
|
||||
{
|
||||
pasteTargetActor = actorNode.Actor;
|
||||
pasteTargetActor = actorNode.Actor.Scene == actorNode.Actor ? actorNode.Actor : actorNode.Actor.Parent;
|
||||
}
|
||||
|
||||
// Create paste action
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace FlaxEditor.Modules
|
||||
private bool _updateOrFixedUpdateWasCalled;
|
||||
private long _breakpointHangFlag;
|
||||
private EditorWindow _enterPlayFocusedWindow;
|
||||
private Scene[] _scenesToReload;
|
||||
|
||||
internal SimulationModule(Editor editor)
|
||||
: base(editor)
|
||||
@@ -68,6 +69,22 @@ namespace FlaxEditor.Modules
|
||||
BreakpointHangEnd?.Invoke();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delegates between playing game and playing scenes in editor based on the user's editor preference.
|
||||
/// </summary>
|
||||
public void DelegatePlayOrStopPlayInEditor()
|
||||
{
|
||||
switch (Editor.Options.Options.Interface.PlayButtonAction)
|
||||
{
|
||||
case Options.InterfaceOptions.PlayAction.PlayGame:
|
||||
Editor.Simulation.RequestPlayGameOrStopPlay();
|
||||
return;
|
||||
case Options.InterfaceOptions.PlayAction.PlayScenes:
|
||||
Editor.Simulation.RequestPlayScenesOrStopPlay();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if play mode has been requested.
|
||||
/// </summary>
|
||||
@@ -76,7 +93,7 @@ namespace FlaxEditor.Modules
|
||||
/// <summary>
|
||||
/// Requests start playing in editor.
|
||||
/// </summary>
|
||||
public void RequestStartPlay()
|
||||
public void RequestStartPlayScenes()
|
||||
{
|
||||
if (Editor.StateMachine.IsEditMode)
|
||||
{
|
||||
@@ -89,6 +106,57 @@ namespace FlaxEditor.Modules
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests playing game start or stop in editor from the project's configured FirstScene.
|
||||
/// </summary>
|
||||
public void RequestPlayGameOrStopPlay()
|
||||
{
|
||||
if (Editor.StateMachine.IsPlayMode)
|
||||
{
|
||||
RequestStopPlay();
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestStartPlayGame();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests start playing in editor from the project's configured FirstScene.
|
||||
/// </summary>
|
||||
public void RequestStartPlayGame()
|
||||
{
|
||||
if (!Editor.StateMachine.IsEditMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var firstScene = Content.Settings.GameSettings.Load().FirstScene;
|
||||
if (firstScene == Guid.Empty)
|
||||
{
|
||||
if (Level.IsAnySceneLoaded)
|
||||
Editor.Simulation.RequestStartPlayScenes();
|
||||
return;
|
||||
}
|
||||
|
||||
_scenesToReload = Level.Scenes;
|
||||
Level.UnloadAllScenes();
|
||||
Level.LoadScene(firstScene);
|
||||
|
||||
Editor.PlayModeEnd += OnPlayGameEnd;
|
||||
RequestPlayScenesOrStopPlay();
|
||||
}
|
||||
|
||||
private void OnPlayGameEnd()
|
||||
{
|
||||
Editor.PlayModeEnd -= OnPlayGameEnd;
|
||||
|
||||
Level.UnloadAllScenes();
|
||||
|
||||
foreach (var scene in _scenesToReload)
|
||||
Level.LoadScene(scene.ID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests stop playing in editor.
|
||||
/// </summary>
|
||||
@@ -106,14 +174,14 @@ namespace FlaxEditor.Modules
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the playing start or stop in editor.
|
||||
/// Requests the playing scenes start or stop in editor.
|
||||
/// </summary>
|
||||
public void RequestPlayOrStopPlay()
|
||||
public void RequestPlayScenesOrStopPlay()
|
||||
{
|
||||
if (Editor.StateMachine.IsPlayMode)
|
||||
RequestStopPlay();
|
||||
else
|
||||
RequestStartPlay();
|
||||
RequestStartPlayScenes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -39,7 +39,6 @@ namespace FlaxEditor.Modules
|
||||
private bool _progressFailed;
|
||||
|
||||
ContextMenuSingleSelectGroup<int> _numberOfClientsGroup = new ContextMenuSingleSelectGroup<int>();
|
||||
private Scene[] _scenesToReload;
|
||||
|
||||
private ContextMenuButton _menuFileSaveScenes;
|
||||
private ContextMenuButton _menuFileCloseScenes;
|
||||
@@ -556,8 +555,8 @@ namespace FlaxEditor.Modules
|
||||
cm = MenuGame.ContextMenu;
|
||||
cm.VisibleChanged += OnMenuGameShowHide;
|
||||
|
||||
_menuGamePlayGame = cm.AddButton("Play Game", PlayGame);
|
||||
_menuGamePlayCurrentScenes = cm.AddButton("Play Current Scenes", inputOptions.Play.ToString(), PlayScenes);
|
||||
_menuGamePlayGame = cm.AddButton("Play Game", Editor.Simulation.RequestPlayGameOrStopPlay);
|
||||
_menuGamePlayCurrentScenes = cm.AddButton("Play Current Scenes", Editor.Simulation.RequestPlayScenesOrStopPlay);
|
||||
_menuGameStop = cm.AddButton("Stop Game", Editor.Simulation.RequestStopPlay);
|
||||
_menuGamePause = cm.AddButton("Pause", inputOptions.Pause.ToString(), Editor.Simulation.RequestPausePlay);
|
||||
|
||||
@@ -566,8 +565,8 @@ namespace FlaxEditor.Modules
|
||||
_numberOfClientsGroup.AddItemsToContextMenu(numberOfClientsMenu.ContextMenu);
|
||||
|
||||
cm.AddSeparator();
|
||||
cm.AddButton("Cook & Run", CookAndRun).LinkTooltip("Runs Game Cooker to build the game for this platform and runs the game after.");
|
||||
cm.AddButton("Run cooked game", RunCookedGame).LinkTooltip("Runs the game build from the last cooking output. Use Cook&Play or Game Cooker first.");
|
||||
cm.AddButton("Cook & Run", Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip("Runs Game Cooker to build the game for this platform and runs the game after.");
|
||||
cm.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked).LinkTooltip("Runs the game build from the last cooking output. Use Cook&Play or Game Cooker first.");
|
||||
|
||||
// Tools
|
||||
MenuTools = MainMenu.AddButton("Tools");
|
||||
@@ -658,23 +657,23 @@ namespace FlaxEditor.Modules
|
||||
Parent = mainWindow,
|
||||
};
|
||||
|
||||
_toolStripSaveAll = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Save64, Editor.SaveAll).LinkTooltip("Save all (Ctrl+S)");
|
||||
_toolStripSaveAll = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Save64, Editor.SaveAll).LinkTooltip($"Save all ({inputOptions.Save})");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripUndo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Undo64, Editor.PerformUndo).LinkTooltip("Undo (Ctrl+Z)");
|
||||
_toolStripRedo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Redo64, Editor.PerformRedo).LinkTooltip("Redo (Ctrl+Y)");
|
||||
_toolStripUndo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Undo64, Editor.PerformUndo).LinkTooltip($"Undo ({inputOptions.Undo})");
|
||||
_toolStripRedo = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Redo64, Editor.PerformRedo).LinkTooltip($"Redo ({inputOptions.Redo})");
|
||||
ToolStrip.AddSeparator();
|
||||
_toolStripTranslate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Translate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate).LinkTooltip("Change Gizmo tool mode to Translate (1)");
|
||||
_toolStripRotate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Rotate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate).LinkTooltip("Change Gizmo tool mode to Rotate (2)");
|
||||
_toolStripScale = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Scale32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale).LinkTooltip("Change Gizmo tool mode to Scale (3)");
|
||||
_toolStripTranslate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Translate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate).LinkTooltip($"Change Gizmo tool mode to Translate ({inputOptions.TranslateMode})");
|
||||
_toolStripRotate = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Rotate32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate).LinkTooltip($"Change Gizmo tool mode to Rotate ({inputOptions.RotateMode})");
|
||||
_toolStripScale = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Scale32, () => Editor.MainTransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale).LinkTooltip($"Change Gizmo tool mode to Scale ({inputOptions.ScaleMode})");
|
||||
ToolStrip.AddSeparator();
|
||||
|
||||
// Cook scenes
|
||||
_toolStripBuildScenes = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Build64, Editor.BuildScenesOrCancel).LinkTooltip("Build scenes data - CSG, navmesh, static lighting, env probes - configurable via Build Actions in editor options (Ctrl+F10)");
|
||||
|
||||
// Cook and run
|
||||
_toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, CookAndRun).LinkTooltip("Cook & Run - build game for the current platform and run it locally");
|
||||
_toolStripCook = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.ShipIt64, Editor.Windows.GameCookerWin.BuildAndRun).LinkTooltip("Cook & Run - build game for the current platform and run it locally");
|
||||
_toolStripCook.ContextMenu = new ContextMenu();
|
||||
_toolStripCook.ContextMenu.AddButton("Run cooked game", RunCookedGame);
|
||||
_toolStripCook.ContextMenu.AddButton("Run cooked game", Editor.Windows.GameCookerWin.RunCooked);
|
||||
_toolStripCook.ContextMenu.AddSeparator();
|
||||
var numberOfClientsMenu = _toolStripCook.ContextMenu.AddChildMenu("Number of game clients");
|
||||
_numberOfClientsGroup.AddItemsToContextMenu(numberOfClientsMenu.ContextMenu);
|
||||
@@ -682,7 +681,7 @@ namespace FlaxEditor.Modules
|
||||
ToolStrip.AddSeparator();
|
||||
|
||||
// Play
|
||||
_toolStripPlay = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Play64, OnPlayPressed).LinkTooltip("Play Game");
|
||||
_toolStripPlay = (ToolStripButton)ToolStrip.AddButton(Editor.Icons.Play64, Editor.Simulation.DelegatePlayOrStopPlayInEditor).LinkTooltip($"Play In Editor ({inputOptions.Play})");
|
||||
_toolStripPlay.ContextMenu = new ContextMenu();
|
||||
var playSubMenu = _toolStripPlay.ContextMenu.AddChildMenu("Play button action");
|
||||
var playActionGroup = new ContextMenuSingleSelectGroup<InterfaceOptions.PlayAction>();
|
||||
@@ -1039,65 +1038,6 @@ namespace FlaxEditor.Modules
|
||||
Editor.Options.Apply(options);
|
||||
}
|
||||
|
||||
private void OnPlayPressed()
|
||||
{
|
||||
switch (Editor.Options.Options.Interface.PlayButtonAction)
|
||||
{
|
||||
case InterfaceOptions.PlayAction.PlayGame:
|
||||
if (Editor.IsPlayMode)
|
||||
Editor.Simulation.RequestStopPlay();
|
||||
else
|
||||
PlayGame();
|
||||
return;
|
||||
case InterfaceOptions.PlayAction.PlayScenes:
|
||||
PlayScenes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayGame()
|
||||
{
|
||||
var firstScene = GameSettings.Load().FirstScene;
|
||||
if (firstScene == Guid.Empty)
|
||||
{
|
||||
if (Level.IsAnySceneLoaded)
|
||||
Editor.Simulation.RequestStartPlay();
|
||||
return;
|
||||
}
|
||||
|
||||
_scenesToReload = Level.Scenes;
|
||||
Level.UnloadAllScenes();
|
||||
Level.LoadScene(firstScene);
|
||||
|
||||
Editor.PlayModeEnd += OnPlayGameSceneEnding;
|
||||
Editor.Simulation.RequestPlayOrStopPlay();
|
||||
}
|
||||
|
||||
private void OnPlayGameSceneEnding()
|
||||
{
|
||||
Editor.PlayModeEnd -= OnPlayGameSceneEnding;
|
||||
|
||||
Level.UnloadAllScenes();
|
||||
|
||||
foreach (var scene in _scenesToReload)
|
||||
Level.LoadScene(scene.ID);
|
||||
}
|
||||
|
||||
private void PlayScenes()
|
||||
{
|
||||
Editor.Simulation.RequestPlayOrStopPlay();
|
||||
}
|
||||
|
||||
private void CookAndRun()
|
||||
{
|
||||
Editor.Windows.GameCookerWin.BuildAndRun();
|
||||
}
|
||||
|
||||
private void RunCookedGame()
|
||||
{
|
||||
Editor.Windows.GameCookerWin.RunCooked();
|
||||
}
|
||||
|
||||
private void OnMainWindowClosing()
|
||||
{
|
||||
// Clear UI references (GUI cannot be used after window closing)
|
||||
|
||||
@@ -60,6 +60,10 @@ namespace FlaxEditor.Options
|
||||
[EditorDisplay("Common"), EditorOrder(200)]
|
||||
public InputBinding FocusSelection = new InputBinding(KeyboardKeys.F);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Shift+F")]
|
||||
[EditorDisplay("Common"), EditorOrder(200)]
|
||||
public InputBinding LockFocusSelection = new InputBinding(KeyboardKeys.F, KeyboardKeys.Shift);
|
||||
|
||||
[DefaultValue(typeof(InputBinding), "Ctrl+F")]
|
||||
[EditorDisplay("Common"), EditorOrder(210)]
|
||||
public InputBinding Search = new InputBinding(KeyboardKeys.F, KeyboardKeys.Control);
|
||||
|
||||
@@ -138,6 +138,8 @@ namespace FlaxEditor.Actions
|
||||
}
|
||||
}
|
||||
|
||||
// Store previously looked up names and the results
|
||||
Dictionary<string, bool> foundNamesResults = new();
|
||||
for (int i = 0; i < nodeParents.Count; i++)
|
||||
{
|
||||
var node = nodeParents[i];
|
||||
@@ -145,15 +147,28 @@ namespace FlaxEditor.Actions
|
||||
var parent = actor?.Parent;
|
||||
if (parent != null)
|
||||
{
|
||||
bool IsNameValid(string name)
|
||||
{
|
||||
if (!foundNamesResults.TryGetValue(name, out bool found))
|
||||
{
|
||||
found = parent.GetChild(name) != null;
|
||||
foundNamesResults.Add(name, found);
|
||||
}
|
||||
return !found;
|
||||
}
|
||||
|
||||
// Fix name collisions
|
||||
var name = actor.Name;
|
||||
for (int j = 0; j < parent.ChildrenCount; j++)
|
||||
var children = parent.Children;
|
||||
for (int j = 0; j < children.Length; j++)
|
||||
{
|
||||
var child = parent.Children[j];
|
||||
if (child != actor && child.Name == actor.Name)
|
||||
var child = children[j];
|
||||
if (child != actor && child.Name == name)
|
||||
{
|
||||
var children = parent.Children;
|
||||
actor.Name = Utilities.Utils.IncrementNameNumber(name, x => children.All(y => y.Name != x));
|
||||
string newName = Utilities.Utils.IncrementNameNumber(name, x => IsNameValid(x));
|
||||
foundNamesResults[newName] = true;
|
||||
actor.Name = newName;
|
||||
// Multiple actors may have the same name, continue
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -162,10 +177,7 @@ namespace FlaxEditor.Actions
|
||||
}
|
||||
|
||||
for (int i = 0; i < nodeParents.Count; i++)
|
||||
{
|
||||
var node = nodeParents[i];
|
||||
node.PostPaste();
|
||||
}
|
||||
nodeParents[i].PostPaste();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -479,6 +479,7 @@ namespace FlaxEditor.Viewport
|
||||
{
|
||||
InitFpsCounter();
|
||||
_showFpsButon = ViewWidgetShowMenu.AddButton("FPS Counter", () => ShowFpsCounter = !ShowFpsCounter);
|
||||
_showFpsButon.CloseMenuOnClick = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ namespace FlaxEditor.Viewport
|
||||
}
|
||||
}
|
||||
|
||||
private bool _lockedFocus;
|
||||
private double _lockedFocusOffset;
|
||||
private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32);
|
||||
private StaticModel _previewStaticModel;
|
||||
private int _previewModelEntryIndex;
|
||||
@@ -369,9 +371,11 @@ namespace FlaxEditor.Viewport
|
||||
// Show grid widget
|
||||
_showGridButton = ViewWidgetShowMenu.AddButton("Grid", () => Grid.Enabled = !Grid.Enabled);
|
||||
_showGridButton.Icon = Style.Current.CheckBoxTick;
|
||||
_showGridButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show navigation widget
|
||||
_showNavigationButton = ViewWidgetShowMenu.AddButton("Navigation", () => ShowNavigation = !ShowNavigation);
|
||||
_showNavigationButton.CloseMenuOnClick = false;
|
||||
|
||||
// Create camera widget
|
||||
ViewWidgetButtonMenu.AddSeparator();
|
||||
@@ -386,11 +390,43 @@ namespace FlaxEditor.Viewport
|
||||
InputActions.Add(options => options.TranslateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Translate);
|
||||
InputActions.Add(options => options.RotateMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Rotate);
|
||||
InputActions.Add(options => options.ScaleMode, () => TransformGizmo.ActiveMode = TransformGizmoBase.Mode.Scale);
|
||||
InputActions.Add(options => options.LockFocusSelection, LockFocusSelection);
|
||||
InputActions.Add(options => options.FocusSelection, FocusSelection);
|
||||
InputActions.Add(options => options.RotateSelection, RotateSelection);
|
||||
InputActions.Add(options => options.Delete, _editor.SceneEditing.Delete);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
var selection = TransformGizmo.SelectedParents;
|
||||
var requestUnlockFocus = FlaxEngine.Input.Mouse.GetButtonDown(MouseButton.Right) || FlaxEngine.Input.Mouse.GetButtonDown(MouseButton.Left);
|
||||
if (TransformGizmo.SelectedParents.Count == 0 || (requestUnlockFocus && ContainsFocus))
|
||||
{
|
||||
UnlockFocusSelection();
|
||||
}
|
||||
else if (_lockedFocus)
|
||||
{
|
||||
var selectionBounds = BoundingSphere.Empty;
|
||||
for (int i = 0; i < selection.Count; i++)
|
||||
{
|
||||
selection[i].GetEditorSphere(out var sphere);
|
||||
BoundingSphere.Merge(ref selectionBounds, ref sphere, out selectionBounds);
|
||||
}
|
||||
|
||||
if (ContainsFocus)
|
||||
{
|
||||
var viewportFocusDistance = Vector3.Distance(ViewPosition, selectionBounds.Center) / 10f;
|
||||
_lockedFocusOffset -= FlaxEngine.Input.Mouse.ScrollDelta * viewportFocusDistance;
|
||||
}
|
||||
|
||||
var focusDistance = Mathf.Max(selectionBounds.Radius * 2d, 100d);
|
||||
ViewPosition = selectionBounds.Center + (-ViewDirection * (focusDistance + _lockedFocusOffset));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the selection outline effect or restored the default one.
|
||||
/// </summary>
|
||||
@@ -753,6 +789,23 @@ namespace FlaxEditor.Viewport
|
||||
FocusSelection(ref orientation);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lock focus on the current selection gizmo.
|
||||
/// </summary>
|
||||
public void LockFocusSelection()
|
||||
{
|
||||
_lockedFocus = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlock focus on the current selection.
|
||||
/// </summary>
|
||||
public void UnlockFocusSelection()
|
||||
{
|
||||
_lockedFocus = false;
|
||||
_lockedFocusOffset = 0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Focuses the viewport on the current selection of the gizmo.
|
||||
/// </summary>
|
||||
|
||||
@@ -194,16 +194,20 @@ namespace FlaxEditor.Viewport.Previews
|
||||
{
|
||||
// Show Bounds
|
||||
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
|
||||
_showBoundsButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show Skeleton
|
||||
_showNodesButton = ViewWidgetShowMenu.AddButton("Skeleton", () => ShowNodes = !ShowNodes);
|
||||
_showNodesButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show Skeleton Names
|
||||
_showNodesNamesButton = ViewWidgetShowMenu.AddButton("Skeleton Names", () => ShowNodesNames = !ShowNodesNames);
|
||||
_showNodesNamesButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show Floor
|
||||
_showFloorButton = ViewWidgetShowMenu.AddButton("Floor", button => ShowFloor = !ShowFloor);
|
||||
_showFloorButton.IndexInParent = 1;
|
||||
_showFloorButton.CloseMenuOnClick = false;
|
||||
}
|
||||
|
||||
// Enable shadows
|
||||
|
||||
@@ -171,6 +171,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
// Show Default Scene
|
||||
_showDefaultSceneButton = ViewWidgetShowMenu.AddButton("Default Scene", () => ShowDefaultSceneActors = !ShowDefaultSceneActors);
|
||||
_showDefaultSceneButton.Checked = true;
|
||||
_showDefaultSceneButton.CloseMenuOnClick = false;
|
||||
}
|
||||
|
||||
// Setup preview scene
|
||||
|
||||
@@ -199,13 +199,18 @@ namespace FlaxEditor.Viewport.Previews
|
||||
if (useWidgets)
|
||||
{
|
||||
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
|
||||
_showBoundsButton.CloseMenuOnClick = false;
|
||||
_showNormalsButton = ViewWidgetShowMenu.AddButton("Normals", () => ShowNormals = !ShowNormals);
|
||||
_showNormalsButton.CloseMenuOnClick = false;
|
||||
_showTangentsButton = ViewWidgetShowMenu.AddButton("Tangents", () => ShowTangents = !ShowTangents);
|
||||
_showTangentsButton.CloseMenuOnClick = false;
|
||||
_showBitangentsButton = ViewWidgetShowMenu.AddButton("Bitangents", () => ShowBitangents = !ShowBitangents);
|
||||
_showBitangentsButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show Floor
|
||||
_showFloorButton = ViewWidgetShowMenu.AddButton("Floor", button => ShowFloor = !ShowFloor);
|
||||
_showFloorButton.IndexInParent = 1;
|
||||
_showFloorButton.CloseMenuOnClick = false;
|
||||
|
||||
// Show current LOD widget
|
||||
_showCurrentLODButton = ViewWidgetShowMenu.AddButton("Current LOD", button =>
|
||||
@@ -214,6 +219,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
_showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
});
|
||||
_showCurrentLODButton.IndexInParent = 2;
|
||||
_showCurrentLODButton.CloseMenuOnClick = false;
|
||||
|
||||
// Preview LODs mode widget
|
||||
var PreviewLODsMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
|
||||
@@ -186,8 +186,11 @@ namespace FlaxEditor.Viewport.Previews
|
||||
if (!useWidgets)
|
||||
return;
|
||||
_showBoundsButton = ViewWidgetShowMenu.AddButton("Bounds", () => ShowBounds = !ShowBounds);
|
||||
_showBoundsButton.CloseMenuOnClick = false;
|
||||
_showOriginButton = ViewWidgetShowMenu.AddButton("Origin", () => ShowOrigin = !ShowOrigin);
|
||||
_showOriginButton.CloseMenuOnClick = false;
|
||||
_showParticleCounterButton = ViewWidgetShowMenu.AddButton("Particles Counter", () => ShowParticlesCounter = !ShowParticlesCounter);
|
||||
_showParticleCounterButton.CloseMenuOnClick = false;
|
||||
|
||||
// Play/Pause widget
|
||||
{
|
||||
|
||||
@@ -49,6 +49,7 @@ namespace FlaxEditor.Viewport.Previews
|
||||
_showCurrentLODButton.Icon = _showCurrentLOD ? Style.Current.CheckBoxTick : SpriteHandle.Invalid;
|
||||
});
|
||||
_showCurrentLODButton.IndexInParent = 2;
|
||||
_showCurrentLODButton.CloseMenuOnClick = false;
|
||||
|
||||
// PreviewLODS mode widget
|
||||
var PreviewLODSMode = new ViewportWidgetsContainer(ViewportWidgetLocation.UpperRight);
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
private readonly Undo _undo;
|
||||
private object _object;
|
||||
private bool _isRegisteredForScriptsReload;
|
||||
private Label _typeText;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the Json asset object that is being edited.
|
||||
@@ -136,6 +137,22 @@ namespace FlaxEditor.Windows.Assets
|
||||
}
|
||||
}
|
||||
_presenter.Select(_object);
|
||||
|
||||
if (_typeText != null)
|
||||
_typeText.Dispose();
|
||||
var typeText = new ClickableLabel
|
||||
{
|
||||
Text = $"{Asset.DataTypeName}",
|
||||
TooltipText = "Asset data type (full name)",
|
||||
AnchorPreset = AnchorPresets.TopRight,
|
||||
AutoWidth = true,
|
||||
Parent = this,
|
||||
};
|
||||
typeText.LocalX += -(typeText.Width + 4);
|
||||
typeText.LocalY += (_toolstrip.Height - typeText.Height) * 0.5f;
|
||||
typeText.RightClick = () => Clipboard.Text = Asset.DataTypeName;
|
||||
_typeText = typeText;
|
||||
|
||||
_undo.Clear();
|
||||
ClearEditedFlag();
|
||||
|
||||
@@ -175,6 +192,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
_isRegisteredForScriptsReload = false;
|
||||
ScriptsBuilder.ScriptsReloadBegin -= OnScriptsReloadBegin;
|
||||
}
|
||||
_typeText = null;
|
||||
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace FlaxEditor.Windows.Assets
|
||||
// Set paste target if only one actor is selected and no target provided
|
||||
if (pasteTargetActor == null && Selection.Count == 1 && Selection[0] is ActorNode actorNode)
|
||||
{
|
||||
pasteTargetActor = actorNode.Actor;
|
||||
pasteTargetActor = actorNode.Actor.IsPrefabRoot ? actorNode.Actor : actorNode.Actor.Parent;
|
||||
}
|
||||
|
||||
// Create paste action
|
||||
|
||||
@@ -247,8 +247,17 @@ namespace FlaxEditor.Windows
|
||||
for (int i = 0; i < _viewDropdown.Items.Count; i++)
|
||||
{
|
||||
var filterButton = filters.ContextMenu.AddButton(_viewDropdown.Items[i], OnFilterClicked);
|
||||
filterButton.CloseMenuOnClick = false;
|
||||
filterButton.Tag = i;
|
||||
}
|
||||
filters.ContextMenu.ButtonClicked += button =>
|
||||
{
|
||||
foreach (var item in (filters.ContextMenu).Items)
|
||||
{
|
||||
if (item is ContextMenuButton filterButton)
|
||||
filterButton.Checked = _viewDropdown.IsSelected(filterButton.Text);
|
||||
}
|
||||
};
|
||||
filters.ContextMenu.VisibleChanged += control =>
|
||||
{
|
||||
if (!control.Visible)
|
||||
@@ -340,6 +349,9 @@ namespace FlaxEditor.Windows
|
||||
/// <returns>The created renaming popup.</returns>
|
||||
public void Rename(ContentItem item)
|
||||
{
|
||||
if (!item.CanRename)
|
||||
return;
|
||||
|
||||
// Show element in the view
|
||||
Select(item, true);
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ namespace FlaxEditor.Windows
|
||||
Editor.Options.OptionsChanged += OnOptionsChanged;
|
||||
OnOptionsChanged(Editor.Options.Options);
|
||||
|
||||
InputActions.Add(options => options.Play, Editor.Simulation.RequestPlayOrStopPlay);
|
||||
InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor);
|
||||
InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause);
|
||||
InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace FlaxEditor.Windows
|
||||
InputActions.Add(options => options.SelectAll, Editor.SceneEditing.SelectAllScenes);
|
||||
InputActions.Add(options => options.Delete, Editor.SceneEditing.Delete);
|
||||
InputActions.Add(options => options.Search, () => Editor.Windows.SceneWin.Search());
|
||||
InputActions.Add(options => options.Play, Editor.Simulation.RequestPlayOrStopPlay);
|
||||
InputActions.Add(options => options.Play, Editor.Simulation.DelegatePlayOrStopPlayInEditor);
|
||||
InputActions.Add(options => options.Pause, Editor.Simulation.RequestResumeOrPause);
|
||||
InputActions.Add(options => options.StepFrame, Editor.Simulation.RequestPlayOneFrame);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user