diff --git a/CoroutineUtils.cs b/CoroutineUtils.cs
index a8f88ce..a91c31c 100644
--- a/CoroutineUtils.cs
+++ b/CoroutineUtils.cs
@@ -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;
diff --git a/Editor/BuildingUtils.cs b/Editor/BuildingUtils.cs
index b2acc8d..a95774f 100644
--- a/Editor/BuildingUtils.cs
+++ b/Editor/BuildingUtils.cs
@@ -55,7 +55,18 @@ public static class BuildingUtils
BuildDevelopment();
UploadSteam();
}
-
+
+
+ [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()
@@ -63,6 +74,7 @@ public static class BuildingUtils
if(!CanBuild())
return;
BuildWindowsRelease();
+ BuildLinuxRelease();
}
[MenuItem("Tools/Build/All Development")]
@@ -72,6 +84,15 @@ public static class BuildingUtils
return;
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()
@@ -88,6 +109,15 @@ public static class BuildingUtils
return;
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,12 +147,31 @@ 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 +
$"/../../{Application.productName}-Steam/ContentBuilder/content/windows/{Application.productName}.exe";
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()
{
@@ -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}")
{
diff --git a/NEG/UI/UiManager.cs b/NEG/UI/UiManager.cs
index c25e4b3..f55b0da 100644
--- a/NEG/UI/UiManager.cs
+++ b/NEG/UI/UiManager.cs
@@ -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
///
/// Current window that is considered main (focused, lastly opened). Can be null.
///
- 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 mainWindows;
+
protected UiManager(IArea startArea)
{
if (Instance != null)
@@ -58,6 +61,7 @@ namespace NEG.UI
Instance = this;
CurrentArea = startArea;
+ mainWindows = new List();
}
///
@@ -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;
-
- //TODO: select new main window
- }
+ 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)
diff --git a/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs b/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs
new file mode 100644
index 0000000..c9ba380
--- /dev/null
+++ b/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs
@@ -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();
+ }
+ }
+}
\ No newline at end of file
diff --git a/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs.meta b/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs.meta
new file mode 100644
index 0000000..14ed8c2
--- /dev/null
+++ b/NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs.meta
@@ -0,0 +1,3 @@
+fileFormatVersion: 2
+guid: 473c065573984067a824ebf3b605c3ab
+timeCreated: 1695048071
\ No newline at end of file
diff --git a/NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs b/NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs
index 1334558..b7211c5 100644
--- a/NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs
+++ b/NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs
@@ -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;
}
}
diff --git a/NEG/UI/UnityUi/Area/MonoArea.cs b/NEG/UI/UnityUi/Area/MonoArea.cs
index 2829582..535489a 100644
--- a/NEG/UI/UnityUi/Area/MonoArea.cs
+++ b/NEG/UI/UnityUi/Area/MonoArea.cs
@@ -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;
diff --git a/NEG/UI/UnityUi/Area/MonoArea.cs.meta b/NEG/UI/UnityUi/Area/MonoArea.cs.meta
index 958b733..883d00d 100644
--- a/NEG/UI/UnityUi/Area/MonoArea.cs.meta
+++ b/NEG/UI/UnityUi/Area/MonoArea.cs.meta
@@ -1,3 +1,11 @@
-fileFormatVersion: 2
+fileFormatVersion: 2
guid: 39eb59ca1ef60934abb3f0c64169be65
-timeCreated: 1670707479
\ No newline at end of file
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 10
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/NEG/UI/UnityUi/MonoController.cs b/NEG/UI/UnityUi/MonoController.cs
index 7c4afdb..e6c9a7b 100644
--- a/NEG/UI/UnityUi/MonoController.cs
+++ b/NEG/UI/UnityUi/MonoController.cs
@@ -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 controllable;
+ protected MonoWindow ControllableAsWindow => (MonoWindow)controllable.Value;
+
protected virtual void Awake()
{
controllable.Value.OnOpened += OnOpened;
diff --git a/NEG/UI/UnityUi/MonoUiInputManger.cs b/NEG/UI/UnityUi/MonoUiInputManger.cs
index 22cd060..4aac796 100644
--- a/NEG/UI/UnityUi/MonoUiInputManger.cs
+++ b/NEG/UI/UnityUi/MonoUiInputManger.cs
@@ -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: "//*");
//keyboardAction.performed += (context) => CurrentInputSource = EInputSource.Keyboard;
//keyboardAction.Enable();
- var gamepadAction = new InputAction(binding: "//*");
- gamepadAction.performed += (context) => OnSelectionChangeStarted();
- gamepadAction.Enable();
+ //var gamepadAction = new InputAction(binding: "//*");
+ //gamepadAction.performed += (context) => OnSelectionChangeStarted();
+ //gamepadAction.Enable();
var mouseAction = new InputAction(binding: "//*");
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)
diff --git a/NEG/UI/UnityUi/MonoUiManager.cs b/NEG/UI/UnityUi/MonoUiManager.cs
index e5ced8c..dbafda8 100644
--- a/NEG/UI/UnityUi/MonoUiManager.cs
+++ b/NEG/UI/UnityUi/MonoUiManager.cs
@@ -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);
diff --git a/NEG/UI/UnityUi/Window/MonoWindow.cs b/NEG/UI/UnityUi/Window/MonoWindow.cs
index ddbc35a..6536f7c 100644
--- a/NEG/UI/UnityUi/Window/MonoWindow.cs
+++ b/NEG/UI/UnityUi/Window/MonoWindow.cs
@@ -12,6 +12,7 @@ using UnityEngine.Serialization;
namespace NEG.UI.UnityUi.Window
{
+ [DefaultExecutionOrder(10)]
public class MonoWindow : MonoBehaviour, IWindow
{
public event Action