ui-system-fix #4

Merged
BitterSmile merged 12 commits from ui-system-fix into main 2024-02-12 19:06:53 +01:00
17 changed files with 210 additions and 31 deletions

View File

@ -27,6 +27,7 @@ namespace NEG.Utils
action?.Invoke();
}
public static void ActionAfterEndOfFrame(this MonoBehaviour mono, Action action) => mono.StartCoroutine(ActionAtNextFrame(action));
public static IEnumerator ActionAfterEndOfFrame(Action action)
{
yield return WaitForEndOfFrame;

View File

@ -57,12 +57,24 @@ public static class BuildingUtils
}
[MenuItem("Tools/Build/Steam/Demo")]
public static void SteamDemo()
{
if(!CanBuild())
return;
IncreaseBuildNumber();
BuildDemo();
UploadSteam(true);
}
[MenuItem("Tools/Build/All Release")]
public static void BuildRelease()
{
if(!CanBuild())
return;
BuildWindowsRelease();
BuildLinuxRelease();
}
[MenuItem("Tools/Build/All Development")]
@ -73,6 +85,15 @@ public static class BuildingUtils
BuildWindowsDevelopment();
}
[MenuItem("Tools/Build/All Demo")]
public static void BuildDemo()
{
if(!CanBuild())
return;
BuildWindows(true, new[] {"DEMO"});
BuildLinux(true, new[] {"DEMO"});
}
[MenuItem("Tools/Build/Platform/Windows/x64-Development")]
public static void BuildWindowsDevelopment()
{
@ -89,6 +110,15 @@ public static class BuildingUtils
BuildWindows(true);
}
[MenuItem("Tools/Build/Platform/Linux/x64-Release")]
public static void BuildLinuxRelease()
{
if(!CanBuild())
return;
BuildLinux(true);
}
[MenuItem("Tools/Build/Platform/Android/GooglePlay")]
public static void BuildGooglePlay()
{
@ -109,7 +139,7 @@ public static class BuildingUtils
BuildPipeline.BuildPlayer(buildPlayerOptions);
}
private static void BuildWindows(bool release)
private static void BuildWindows(bool release, string[] additionalDefines = default)
{
var buildPlayerOptions = new BuildPlayerOptions { scenes = new string[EditorBuildSettings.scenes.Length] };
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
@ -117,6 +147,8 @@ public static class BuildingUtils
buildPlayerOptions.scenes[i] = EditorBuildSettings.scenes[i].path;
}
buildPlayerOptions.extraScriptingDefines = additionalDefines;
buildPlayerOptions.target = BuildTarget.StandaloneWindows64;
buildPlayerOptions.options = release ? BuildOptions.None : BuildOptions.Development;
buildPlayerOptions.locationPathName = Application.dataPath +
@ -124,6 +156,23 @@ public static class BuildingUtils
BuildPipeline.BuildPlayer(buildPlayerOptions);
}
private static void BuildLinux(bool release, string[] additionalDefines = default)
{
var buildPlayerOptions = new BuildPlayerOptions { scenes = new string[EditorBuildSettings.scenes.Length] };
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
{
buildPlayerOptions.scenes[i] = EditorBuildSettings.scenes[i].path;
}
buildPlayerOptions.extraScriptingDefines = additionalDefines;
buildPlayerOptions.target = BuildTarget.StandaloneLinux64;
buildPlayerOptions.options = release ? BuildOptions.None : BuildOptions.Development;
buildPlayerOptions.locationPathName = Application.dataPath +
$"/../../{Application.productName}-Steam/ContentBuilder/content/linux/{Application.productName}.x86_64";
BuildPipeline.BuildPlayer(buildPlayerOptions);
}
private static void IncreaseBuildNumber()
{
string[] versionParts = PlayerSettings.bundleVersion.Split('.');
@ -135,9 +184,13 @@ public static class BuildingUtils
PlayerSettings.bundleVersion = string.Join(".", versionParts);
}
private static void UploadSteam()
private static void UploadSteam(bool demo = false)
{
string command = $"cd {Application.dataPath}/../../{Application.productName}-Steam/ContentBuilder && run_build.bat";
string command = $"cd {Application.dataPath}/../../{Application.productName}-Steam/ContentBuilder && push_build.bat";
if (demo)
{
command = $"cd {Application.dataPath}/../../{Application.productName}-Steam/ContentBuilder && push_demo.bat";
}
var processInfo = new ProcessStartInfo("cmd.exe", $"/c {command}")
{

View File

@ -6,6 +6,7 @@ using NEG.Utils;
using NegUtils.NEG.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace NEG.UI
@ -34,7 +35,7 @@ namespace NEG.UI
/// <summary>
/// Current window that is considered main (focused, lastly opened). Can be null.
/// </summary>
public IWindow CurrentMainWindow { get; protected set; }
public IWindow CurrentMainWindow => mainWindows.LastOrDefault();
public PopupData CurrentPopup => currentShownPopup.data;
@ -47,6 +48,8 @@ namespace NEG.UI
//TODO: localize
private string localizedYes = "Yes", localizedNo = "No", localizedOk = "Ok";
private List<IWindow> mainWindows;
protected UiManager(IArea startArea)
{
if (Instance != null)
@ -58,6 +61,7 @@ namespace NEG.UI
Instance = this;
CurrentArea = startArea;
mainWindows = new List<IWindow>();
}
/// <summary>
@ -146,16 +150,13 @@ namespace NEG.UI
public virtual void Dispose() => Instance = null;
public void SetMainWindow(IWindow window) => CurrentMainWindow = window;
public void SetMainWindow(IWindow window) => mainWindows.Add(window);
public void OnWindowClosed(IWindow window)
{
if(CurrentMainWindow != window)
return;
public void MainWindowClosed(IWindow window) => mainWindows.Remove(window);
public void OnWindowClosed(IWindow window) => MainWindowClosed(window);
//TODO: select new main window
}
protected void PopupClosed(PopupData data)
{
if (currentShownPopup.data != data)
@ -169,7 +170,7 @@ namespace NEG.UI
protected void SetDefaultPopup(IDefaultPopup popup) => currentDefaultPopup = popup;
private void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
protected virtual void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
{
if (forceShow)
{
@ -183,6 +184,8 @@ namespace NEG.UI
while (popupsToShow.TryDequeue(out var d, out int p))
{
if(d == null)
continue;
if(!d.IsValid)
continue;
if(d == currentShownPopup.data)

View File

@ -0,0 +1,17 @@
using NEG.UI.UnityUi.Window;
using NEG.UI.Window;
using UnityEngine;
namespace NEG.UI.Area
{
public class AutoOpenWindowWhenNoOther : MonoBehaviour
{
[SerializeField] private MonoWindow window;
private void Start()
{
if(UiManager.Instance.CurrentMainWindow == null)
window.Open();
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 473c065573984067a824ebf3b605c3ab
timeCreated: 1695048071

View File

@ -12,7 +12,7 @@ namespace NEG.UI.Area
protected override void OnBackUsed(IControllable.BackUsed backUsed)
{
base.OnBackUsed(backUsed);
UiManager.Instance.CurrentMainWindow.Close();
UiManager.Instance.CurrentMainWindow?.Close();
backUsed.Used = true;
}
}

View File

@ -36,7 +36,7 @@ namespace NEG.UI.Area
public void OpenWindow(IWindow window, object data = null) => DefaultWindowSlot.AttachWindow(window, data);
private void Awake()
protected virtual void Awake()
{
if (setAsDefaultArea)
UiManager.Instance.CurrentArea = this;

View File

@ -1,3 +1,11 @@
fileFormatVersion: 2
fileFormatVersion: 2
guid: 39eb59ca1ef60934abb3f0c64169be65
timeCreated: 1670707479
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 10
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,4 +1,5 @@
using KBCore.Refs;
using NEG.UI.UnityUi.Window;
using NegUtils.NEG.UI;
using System;
using UnityEngine;
@ -11,6 +12,8 @@ namespace NEG.UI.UnityUi
[SerializeField, Self] protected InterfaceRef<IControllable> controllable;
protected MonoWindow ControllableAsWindow => (MonoWindow)controllable.Value;
protected virtual void Awake()
{
controllable.Value.OnOpened += OnOpened;

View File

@ -1,4 +1,5 @@
using UnityEngine;
using NEG.UI.UnityUi.Window;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.UI;
@ -11,16 +12,16 @@ namespace NEG.UI.UnityUi
Direction
}
public class UiInputModule { }
public class UiInputModule { public SelectionSource CurrentSelectionSource { get; protected set; }}
public class DefaultInputModule : UiInputModule
{
public SelectionSource CurrentSelectionSource { get; private set; }
public DefaultInputModule()
{
var defaultActions = new DefaultInputActions();
InputActionReference.Create(defaultActions.UI.Navigate).action.performed += (ctx) => OnSelectionChangeStarted();
InputActionReference.Create(defaultActions.UI.Cancel).action.performed +=
(_) => UiManager.Instance.UseBack();
defaultActions.Enable();
if (Gamepad.current != null)
@ -31,9 +32,9 @@ namespace NEG.UI.UnityUi
//var keyboardAction = new InputAction(binding: "/<Keyboard>/*");
//keyboardAction.performed += (context) => CurrentInputSource = EInputSource.Keyboard;
//keyboardAction.Enable();
var gamepadAction = new InputAction(binding: "/<Gamepad>/*");
gamepadAction.performed += (context) => OnSelectionChangeStarted();
gamepadAction.Enable();
//var gamepadAction = new InputAction(binding: "/<Gamepad>/*");
//gamepadAction.performed += (context) => OnSelectionChangeStarted();
//gamepadAction.Enable();
var mouseAction = new InputAction(binding: "/<Mouse>/*");
mouseAction.performed += (context) =>
@ -47,15 +48,37 @@ namespace NEG.UI.UnityUi
private void OnSelectionChangeStarted()
{
if(CurrentSelectionSource == SelectionSource.Direction)
if(CurrentSelectionSource == SelectionSource.Direction && EventSystem.current.currentSelectedGameObject != null)
return;
SetDirectionInput();
}
private void SetDirectionInput()
{
if (EventSystem.current == null || MonoUiManager.Instance == null )
{
return;
}
CurrentSelectionSource = SelectionSource.Direction;
Cursor.visible = false;
if (EventSystem.current.currentSelectedGameObject == null && MonoUiManager.Instance.CurrentMainWindow != null)
{
EventSystem.current.SetSelectedGameObject(((MonoWindow)MonoUiManager.Instance.CurrentMainWindow).DefaultSelectedItem);
return;
}
var data = new PointerEventData(EventSystem.current);
var currentSelected = EventSystem.current.currentSelectedGameObject;
if (currentSelected != null)
{
for (var current = EventSystem.current.currentSelectedGameObject.transform;
current != null;
current = current.parent)
{
ExecuteEvents.Execute(current.gameObject, data, ExecuteEvents.pointerExitHandler);
}
}
EventSystem.current.SetSelectedGameObject(currentSelected);
}
private void SetPointerInput()
@ -72,6 +95,8 @@ namespace NEG.UI.UnityUi
if (EventSystem.current.currentInputModule == null)
return;
EventSystem.current.SetSelectedGameObject(null);
var module = (InputSystemUIInputModule)EventSystem.current.currentInputModule;
var result = module.GetLastRaycastResult(0);
if(result.gameObject == null)

View File

@ -3,11 +3,13 @@ using NEG.UI.Popup;
using NEG.UI.UnityUi.Buttons.Reaction;
using NEG.UI.UnityUi.Buttons.Settings;
using NEG.UI.UnityUi.Popup;
using NEG.UI.UnityUi.Window;
using NEG.Utils;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Assertions;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using Object = UnityEngine.Object;
@ -68,6 +70,20 @@ namespace NEG.UI.UnityUi
Instance = null;
}
protected override void UpdatePopupsState(bool forceShow, int priority = 0, PopupData data = null)
{
base.UpdatePopupsState(forceShow, priority, data);
if(inputModule.CurrentSelectionSource != SelectionSource.Direction)
return;
if (CurrentPopup == null && (EventSystem.current.currentSelectedGameObject == null || !EventSystem.current.currentSelectedGameObject.activeInHierarchy))
{
if(((MonoWindow)CurrentMainWindow).DefaultSelectedItem == null)
return;
EventSystem.current.SetSelectedGameObject(((MonoWindow)CurrentMainWindow).DefaultSelectedItem);
}
}
private void SpawnDefaultPopup()
{
var canvas = Object.Instantiate(canvasPrefab);

View File

@ -12,6 +12,7 @@ using UnityEngine.Serialization;
namespace NEG.UI.UnityUi.Window
{
[DefaultExecutionOrder(10)]
public class MonoWindow : MonoBehaviour, IWindow
{
public event Action<object> OnOpened;
@ -23,7 +24,10 @@ namespace NEG.UI.UnityUi.Window
public bool IsMainWindow { get; private set; }
public bool IsOpened { get; protected set; }
private IWindowSlot DefaultWindowSlot => windowSlots[0];
public GameObject DefaultSelectedItem => defaultSelectedItem;
[SerializeField] private List<MonoWindowSlot> windowSlots;
@ -32,6 +36,7 @@ namespace NEG.UI.UnityUi.Window
public void SetOpenedState(IWindowSlot parentSlot, object data)
{
gameObject.SetActive(true);
IsOpened = true;
Parent = parentSlot;
EventSystem.current.SetSelectedGameObject(defaultSelectedItem);
if (parentSlot.OpenWindowAsMain)
@ -42,6 +47,7 @@ namespace NEG.UI.UnityUi.Window
public void SetClosedState()
{
gameObject.SetActive(false);
IsOpened = false;
Parent = null;
((ISlotsHolder)this).CloseAllWindows();
UiManager.Instance.OnWindowClosed(this);
@ -54,6 +60,14 @@ namespace NEG.UI.UnityUi.Window
private void Awake() => ((IWindow)this).SetHiddenState();
private void OnDestroy()
{
if (IsOpened)
{
UiManager.Instance.OnWindowClosed(this);
}
}
private void OnValidate()
{
#if !NEG_UI_DISABLE_WARNING_DEFAULT_SELECTION

View File

@ -1,3 +1,11 @@
fileFormatVersion: 2
fileFormatVersion: 2
guid: 85d136d6850728d4b96c26fa286ffe3c
timeCreated: 1670709296
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 11
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
using NegUtils.NEG.UI;
namespace NEG.UI.UnityUi.Window
{
public class NoReactionOnBack : MonoController
{
protected override void OnBackUsed(IControllable.BackUsed backUsed)
{
base.OnBackUsed(backUsed);
backUsed.Used = true;
}
}
}

View File

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c4a5380c95244c76ac79f820d16ea11c
timeCreated: 1702565120

View File

@ -24,7 +24,13 @@ namespace NEG.UI.WindowSlot
window.SetOpenedState(this, data);
}
public override void DetachWindow(IWindow window) => CurrentWindow = null;
public override void DetachWindow(IWindow window)
{
if(UiManager.Instance.CurrentMainWindow == window)
UiManager.Instance.MainWindowClosed(window);
CurrentWindow = null;
}
public override void CloseAllWindows() => CurrentWindow = null;
}
}

View File

@ -1,7 +1,10 @@
using NEG.UI.UnityUi.WindowSlot;
using NEG.UI;
using NEG.UI.UnityUi.Window;
using NEG.UI.UnityUi.WindowSlot;
using NEG.UI.Window;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.EventSystems;
namespace NegUtils.NEG.UI.UnityUi.WindowSlot
{
@ -41,8 +44,11 @@ namespace NegUtils.NEG.UI.UnityUi.WindowSlot
window.SetClosedState();
windowsHistory.Remove(window);
if (window != currentWindow || windowsHistory.Count == 0) return;
windowsHistory[^1].SeVisibleState();
currentWindow = windowsHistory[^1];
currentWindow.SeVisibleState();
if(UiManager.Instance.CurrentMainWindow == window)
UiManager.Instance.MainWindowClosed(window);
EventSystem.current.SetSelectedGameObject(((MonoWindow)currentWindow).DefaultSelectedItem);
}
public override void CloseAllWindows()
{