Compare commits
65 Commits
mo/localiz
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d14e2ca055 | |||
| d0d7134b68 | |||
| 987c7b1be2 | |||
| f7a7427610 | |||
| b3c1d2fd14 | |||
| 5dd6a3b0de | |||
| e6af704f30 | |||
| 85dee79cc8 | |||
| 20e281f9dd | |||
| f8d8b9fd12 | |||
| a9d35a5447 | |||
| bcb239587b | |||
| e819020474 | |||
| ae89122e42 | |||
| 46d192ea27 | |||
| 1818d99caf | |||
| 8d5b903b1a | |||
| d9fc097783 | |||
| da89d7a7fc | |||
| cd8c819585 | |||
| 566430650f | |||
| 164fd2f794 | |||
| 0148de0db7 | |||
| 610179c21d | |||
| ebfeb14515 | |||
| 1abfcc0042 | |||
| 6b01de0095 | |||
| 8835f620e9 | |||
| ab5a33742a | |||
| b7dfa7bffa | |||
| b7aa670e70 | |||
| d06350da06 | |||
| 15ea7f7328 | |||
| aafd5dbc75 | |||
| fb90337a3f | |||
| 0007e30aca | |||
| 33d0a9078f | |||
| 63d3d908e8 | |||
| a83c4cfb3b | |||
| 85daf89041 | |||
| 9c91269a9e | |||
| f3f386d4c0 | |||
| 9e60fdf32d | |||
| 17f48f7eb2 | |||
| 34807988d8 | |||
| f837aec845 | |||
| 611f417d5e | |||
| 1f2c251d0c | |||
| 8fe292818e | |||
| c0dd3dfdc5 | |||
| 1e66136bfc | |||
| e30470d27a | |||
| 4239816cd8 | |||
| 7bf4512c43 | |||
| 7aecbeb240 | |||
| 42dbfc8827 | |||
| 359b616be9 | |||
| ad760f57b0 | |||
| 482e70b21a | |||
| 989a21a2c5 | |||
| c0923cc884 | |||
| 055df4e427 | |||
| 32b208d1b6 | |||
| 9647327168 | |||
| 6c19b566d0 |
@ -1,5 +1,4 @@
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
|
||||||
|
|
||||||
namespace NEG.Utils
|
namespace NEG.Utils
|
||||||
{
|
{
|
||||||
@ -10,4 +9,3 @@ namespace NEG.Utils
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,8 @@ namespace NEG.Utils.Collections
|
|||||||
public static class DictionaryExtensions
|
public static class DictionaryExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds given value to a dictionary if there was no element at given <paramref name="key"/>, replaces element with <paramref name="value"> otherwise.
|
/// Adds given value to a dictionary if there was no element at given <paramref name="key" />, replaces element with
|
||||||
|
/// <paramref name="value"> otherwise.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>true if element was added, false if it was replaced</returns>
|
/// <returns>true if element was added, false if it was replaced</returns>
|
||||||
public static bool AddOrUpdate<K, V>(this Dictionary<K, V> dict, K key, V value)
|
public static bool AddOrUpdate<K, V>(this Dictionary<K, V> dict, K key, V value)
|
||||||
@ -15,24 +16,20 @@ namespace NEG.Utils.Collections
|
|||||||
dict[key] = value;
|
dict[key] = value;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
dict.Add(key, value);
|
dict.Add(key, value);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value from the dictionary under a specified key or adds it if did not exist and returns <paramref name="defaultValue"/>.
|
/// Gets a value from the dictionary under a specified key or adds it if did not exist and returns
|
||||||
|
/// <paramref name="defaultValue" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>value under a given <paramref name="key" /> if it exists, <paramref name="defaultValue" /> otherwise</returns>
|
/// <returns>value under a given <paramref name="key" /> if it exists, <paramref name="defaultValue" /> otherwise</returns>
|
||||||
public static V GetOrSetToDefault<K, V>(this Dictionary<K, V> dict, K key, V defaultValue)
|
public static V GetOrSetToDefault<K, V>(this Dictionary<K, V> dict, K key, V defaultValue)
|
||||||
{
|
{
|
||||||
if (dict.TryGetValue(key, out V value))
|
if (dict.TryGetValue(key, out var value)) return value;
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
dict.Add(key, defaultValue);
|
dict.Add(key, defaultValue);
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|||||||
@ -6,20 +6,15 @@ namespace NEG.Utils
|
|||||||
{
|
{
|
||||||
public static class CoroutineUtils
|
public static class CoroutineUtils
|
||||||
{
|
{
|
||||||
private static readonly WaitForEndOfFrame WaitForEndOfFrame = new WaitForEndOfFrame();
|
private static readonly WaitForEndOfFrame WaitForEndOfFrame = new();
|
||||||
|
|
||||||
public static IEnumerator WaitForFrames(int count)
|
public static IEnumerator WaitForFrames(int count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++) yield return null;
|
||||||
{
|
|
||||||
yield return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ActionAfterFrames(this MonoBehaviour mono, int count, Action action)
|
public static void ActionAfterFrames(this MonoBehaviour mono, int count, Action action) =>
|
||||||
{
|
|
||||||
mono.StartCoroutine(ActionAfterFrames(count, action));
|
mono.StartCoroutine(ActionAfterFrames(count, action));
|
||||||
}
|
|
||||||
|
|
||||||
public static IEnumerator ActionAfterFrames(int count, Action action)
|
public static IEnumerator ActionAfterFrames(int count, Action action)
|
||||||
{
|
{
|
||||||
@ -27,19 +22,26 @@ namespace NEG.Utils
|
|||||||
action?.Invoke();
|
action?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ActionAfterEndOfFrame(this MonoBehaviour mono, Action action) =>
|
||||||
|
mono.StartCoroutine(ActionAtNextFrame(action));
|
||||||
|
|
||||||
public static IEnumerator ActionAfterEndOfFrame(Action action)
|
public static IEnumerator ActionAfterEndOfFrame(Action action)
|
||||||
{
|
{
|
||||||
yield return WaitForEndOfFrame;
|
yield return WaitForEndOfFrame;
|
||||||
action?.Invoke();
|
action?.Invoke();
|
||||||
}
|
}
|
||||||
public static void ActionAtNextFrame(this MonoBehaviour mono, Action action) => mono.StartCoroutine(ActionAtNextFrame(action));
|
|
||||||
|
public static void ActionAtNextFrame(this MonoBehaviour mono, Action action) =>
|
||||||
|
mono.StartCoroutine(ActionAtNextFrame(action));
|
||||||
|
|
||||||
public static IEnumerator ActionAtNextFrame(Action action)
|
public static IEnumerator ActionAtNextFrame(Action action)
|
||||||
{
|
{
|
||||||
yield return null;
|
yield return null;
|
||||||
action?.Invoke();
|
action?.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ActionAfterTime(this MonoBehaviour mono, float time, Action action) => mono.StartCoroutine(ActionAfterTime(time, action));
|
public static void ActionAfterTime(this MonoBehaviour mono, float time, Action action) =>
|
||||||
|
mono.StartCoroutine(ActionAfterTime(time, action));
|
||||||
|
|
||||||
public static IEnumerator ActionAfterTime(float time, Action action)
|
public static IEnumerator ActionAfterTime(float time, Action action)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,13 +1,45 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using UnityEngine;
|
using System.Linq;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEditor.Build;
|
||||||
|
using UnityEngine;
|
||||||
using Debug = UnityEngine.Debug;
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
public static class BuildingUtils
|
public static class BuildingUtils
|
||||||
{
|
{
|
||||||
|
private const string SteamBuildDefine = "STEAM_BUILD";
|
||||||
|
|
||||||
|
[MenuItem("Tools/PrepareForBuild", priority = -10)]
|
||||||
|
public static void PrepareForBuild()
|
||||||
|
{
|
||||||
|
var namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(
|
||||||
|
BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget));
|
||||||
|
string[] args = PlayerSettings.GetAdditionalCompilerArguments(namedBuildTarget);
|
||||||
|
var argsList = args.ToList();
|
||||||
|
argsList.Remove(SteamBuildDefine);
|
||||||
|
PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, argsList.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/PlatformDefines/Steam", priority = -1)]
|
||||||
|
public static void SetDefinesForSteam()
|
||||||
|
{
|
||||||
|
PrepareForBuild();
|
||||||
|
|
||||||
|
var namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(
|
||||||
|
BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget));
|
||||||
|
string[] args = PlayerSettings.GetAdditionalCompilerArguments(namedBuildTarget);
|
||||||
|
var argsList = args.ToList();
|
||||||
|
argsList.Add(SteamBuildDefine);
|
||||||
|
PlayerSettings.SetScriptingDefineSymbols(namedBuildTarget, argsList.ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[MenuItem("Tools/Build/Steam/Release")]
|
[MenuItem("Tools/Build/Steam/Release")]
|
||||||
public static void SteamRelease()
|
public static void SteamRelease()
|
||||||
{
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
|
||||||
IncreaseBuildNumber();
|
IncreaseBuildNumber();
|
||||||
BuildRelease();
|
BuildRelease();
|
||||||
UploadSteam();
|
UploadSteam();
|
||||||
@ -16,38 +48,102 @@ public static class BuildingUtils
|
|||||||
[MenuItem("Tools/Build/Steam/Development")]
|
[MenuItem("Tools/Build/Steam/Development")]
|
||||||
public static void SteamDevelopment()
|
public static void SteamDevelopment()
|
||||||
{
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
|
||||||
IncreaseBuildNumber();
|
IncreaseBuildNumber();
|
||||||
BuildDevelopment();
|
BuildDevelopment();
|
||||||
UploadSteam();
|
UploadSteam();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MenuItem("Tools/Build/Steam/Demo")]
|
||||||
|
public static void SteamDemo()
|
||||||
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
|
||||||
|
IncreaseBuildNumber();
|
||||||
|
BuildDemo();
|
||||||
|
UploadSteam(true);
|
||||||
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Build/All Release")]
|
[MenuItem("Tools/Build/All Release")]
|
||||||
public static void BuildRelease()
|
public static void BuildRelease()
|
||||||
{
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
BuildWindowsRelease();
|
BuildWindowsRelease();
|
||||||
|
BuildLinuxRelease();
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Build/All Development")]
|
[MenuItem("Tools/Build/All Development")]
|
||||||
public static void BuildDevelopment()
|
public static void BuildDevelopment()
|
||||||
{
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
BuildWindowsDevelopment();
|
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")]
|
[MenuItem("Tools/Build/Platform/Windows/x64-Development")]
|
||||||
public static void BuildWindowsDevelopment() => BuildWindows(false);
|
public static void BuildWindowsDevelopment()
|
||||||
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
BuildWindows(false);
|
||||||
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Build/Platform/Windows/x64-Release")]
|
[MenuItem("Tools/Build/Platform/Windows/x64-Release")]
|
||||||
public static void BuildWindowsRelease() => BuildWindows(true);
|
public static void BuildWindowsRelease()
|
||||||
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
BuildWindows(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Build/Platform/Linux/x64-Release")]
|
||||||
|
public static void BuildLinuxRelease()
|
||||||
|
{
|
||||||
|
if (!CanBuild())
|
||||||
|
return;
|
||||||
|
BuildLinux(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void BuildWindows(bool release)
|
[MenuItem("Tools/Build/Platform/Android/GooglePlay")]
|
||||||
|
public static void BuildGooglePlay()
|
||||||
|
{
|
||||||
|
IncreaseBuildNumber();
|
||||||
|
PlayerSettings.Android.bundleVersionCode++;
|
||||||
|
EditorUserBuildSettings.buildAppBundle = true;
|
||||||
|
|
||||||
|
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.target = BuildTarget.Android;
|
||||||
|
buildPlayerOptions.options = BuildOptions.None;
|
||||||
|
buildPlayerOptions.locationPathName = Application.dataPath +
|
||||||
|
$"/../../{Application.productName}-GooglePlay/{Application.productName}.aab";
|
||||||
|
BuildPipeline.BuildPlayer(buildPlayerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void BuildWindows(bool release, string[] additionalDefines = default)
|
||||||
{
|
{
|
||||||
var buildPlayerOptions = new BuildPlayerOptions { scenes = new string[EditorBuildSettings.scenes.Length] };
|
var buildPlayerOptions = new BuildPlayerOptions { scenes = new string[EditorBuildSettings.scenes.Length] };
|
||||||
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
|
for (int i = 0; i < EditorBuildSettings.scenes.Length; i++)
|
||||||
{
|
|
||||||
buildPlayerOptions.scenes[i] = EditorBuildSettings.scenes[i].path;
|
buildPlayerOptions.scenes[i] = EditorBuildSettings.scenes[i].path;
|
||||||
}
|
|
||||||
|
buildPlayerOptions.extraScriptingDefines = additionalDefines;
|
||||||
|
|
||||||
buildPlayerOptions.target = BuildTarget.StandaloneWindows64;
|
buildPlayerOptions.target = BuildTarget.StandaloneWindows64;
|
||||||
buildPlayerOptions.options = release ? BuildOptions.None : BuildOptions.Development;
|
buildPlayerOptions.options = release ? BuildOptions.None : BuildOptions.Development;
|
||||||
@ -56,29 +152,73 @@ public static class BuildingUtils
|
|||||||
BuildPipeline.BuildPlayer(buildPlayerOptions);
|
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()
|
private static void IncreaseBuildNumber()
|
||||||
{
|
{
|
||||||
string[] versionParts = PlayerSettings.bundleVersion.Split('.');
|
string[] versionParts = PlayerSettings.bundleVersion.Split('.');
|
||||||
if (versionParts.Length != 3 || !int.TryParse(versionParts[2], out int version)) {
|
if (versionParts.Length != 3 || !int.TryParse(versionParts[2], out int version))
|
||||||
|
{
|
||||||
Debug.LogError("IncreaseBuildNumber failed to update version " + PlayerSettings.bundleVersion);
|
Debug.LogError("IncreaseBuildNumber failed to update version " + PlayerSettings.bundleVersion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
versionParts[2] = (version + 1).ToString();
|
versionParts[2] = (version + 1).ToString();
|
||||||
PlayerSettings.bundleVersion = string.Join(".", versionParts);
|
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}")
|
var processInfo = new ProcessStartInfo("cmd.exe", $"/c {command}")
|
||||||
{
|
{
|
||||||
CreateNoWindow = true,
|
CreateNoWindow = true, UseShellExecute = false
|
||||||
UseShellExecute = false
|
|
||||||
};
|
};
|
||||||
var process = Process.Start(processInfo);
|
var process = Process.Start(processInfo);
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
Debug.Log(process.ExitCode);
|
Debug.Log(process.ExitCode);
|
||||||
process.Close();
|
process.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool CanBuild()
|
||||||
|
{
|
||||||
|
if (CanBuildUtil())
|
||||||
|
return true;
|
||||||
|
Debug.LogError(
|
||||||
|
"Cannot build with defines set in project, please use PrepareForBuild and wait for scripts recompilation");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CanBuildUtil()
|
||||||
|
{
|
||||||
|
var namedBuildTarget = NamedBuildTarget.FromBuildTargetGroup(
|
||||||
|
BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget));
|
||||||
|
string[] args = PlayerSettings.GetAdditionalCompilerArguments(namedBuildTarget);
|
||||||
|
var argsList = args.ToList();
|
||||||
|
|
||||||
|
if (argsList.Contains(SteamBuildDefine))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -8,14 +8,19 @@ namespace NEG.Utils.Editor.ComponentsAdditionalItems
|
|||||||
{
|
{
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full HD horizontal", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full HD horizontal", false, 2000)]
|
||||||
public static void SetFullHdHorizontal(MenuCommand command) => SetComponent(command, 1920, 1080);
|
public static void SetFullHdHorizontal(MenuCommand command) => SetComponent(command, 1920, 1080);
|
||||||
|
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full HD vertical", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full HD vertical", false, 2000)]
|
||||||
public static void SetFullHdVertical(MenuCommand command) => SetComponent(command, 1080, 1920);
|
public static void SetFullHdVertical(MenuCommand command) => SetComponent(command, 1080, 1920);
|
||||||
|
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full 2k horizontal", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full 2k horizontal", false, 2000)]
|
||||||
public static void Set2KHorizontal(MenuCommand command) => SetComponent(command, 2560, 1440);
|
public static void Set2KHorizontal(MenuCommand command) => SetComponent(command, 2560, 1440);
|
||||||
|
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full 2k vertical", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full 2k vertical", false, 2000)]
|
||||||
public static void Set2KVertical(MenuCommand command) => SetComponent(command, 1440, 2560);
|
public static void Set2KVertical(MenuCommand command) => SetComponent(command, 1440, 2560);
|
||||||
|
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full 4k horizontal", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full 4k horizontal", false, 2000)]
|
||||||
public static void Set4KHorizontal(MenuCommand command) => SetComponent(command, 3840, 2160);
|
public static void Set4KHorizontal(MenuCommand command) => SetComponent(command, 3840, 2160);
|
||||||
|
|
||||||
[MenuItem("CONTEXT/CanvasScaler/Full 4k vertical", false, 2000)]
|
[MenuItem("CONTEXT/CanvasScaler/Full 4k vertical", false, 2000)]
|
||||||
public static void Set4KVertical(MenuCommand command) => SetComponent(command, 2160, 3840);
|
public static void Set4KVertical(MenuCommand command) => SetComponent(command, 2160, 3840);
|
||||||
|
|
||||||
|
|||||||
@ -11,31 +11,26 @@
|
|||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using UnityEngine;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using Debug = UnityEngine.Debug;
|
||||||
|
|
||||||
namespace TheGamedevGuru
|
namespace TheGamedevGuru
|
||||||
{
|
{
|
||||||
public class EditorInstanceCreator : EditorWindow
|
public class EditorInstanceCreator : EditorWindow
|
||||||
{
|
{
|
||||||
string _projectInstanceName;
|
private string _extraSubdirectories;
|
||||||
string _extraSubdirectories;
|
private bool _includeProjectSettings = true;
|
||||||
bool _includeProjectSettings = true;
|
private string _projectInstanceName;
|
||||||
|
|
||||||
[MenuItem("Window/The Gamedev Guru/Editor Instance Creator")]
|
private void OnGUI()
|
||||||
static void Init()
|
|
||||||
{
|
|
||||||
((EditorInstanceCreator)EditorWindow.GetWindow(typeof(EditorInstanceCreator))).Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnGUI()
|
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_projectInstanceName))
|
if (string.IsNullOrEmpty(_projectInstanceName))
|
||||||
{
|
|
||||||
_projectInstanceName = PlayerSettings.productName + "_Slave_1";
|
_projectInstanceName = PlayerSettings.productName + "_Slave_1";
|
||||||
}
|
|
||||||
|
|
||||||
EditorGUILayout.Separator();
|
EditorGUILayout.Separator();
|
||||||
EditorGUILayout.LabelField("The Gamedev Guru - Project Instance Creator");
|
EditorGUILayout.LabelField("The Gamedev Guru - Project Instance Creator");
|
||||||
@ -53,19 +48,20 @@ namespace TheGamedevGuru
|
|||||||
EditorGUILayout.Separator();
|
EditorGUILayout.Separator();
|
||||||
|
|
||||||
if (GUILayout.Button("Create"))
|
if (GUILayout.Button("Create"))
|
||||||
{
|
|
||||||
CreateProjectInstance(_projectInstanceName, _includeProjectSettings, _extraSubdirectories);
|
CreateProjectInstance(_projectInstanceName, _includeProjectSettings, _extraSubdirectories);
|
||||||
}
|
|
||||||
|
|
||||||
if (GUILayout.Button("Help"))
|
if (GUILayout.Button("Help"))
|
||||||
{
|
|
||||||
Application.OpenURL("https://thegamedev.guru/multiple-unity-editor-instances-within-a-single-project/");
|
Application.OpenURL("https://thegamedev.guru/multiple-unity-editor-instances-within-a-single-project/");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static void CreateProjectInstance(string projectInstanceName, bool includeProjectSettings, string extraSubdirectories)
|
[MenuItem("Window/The Gamedev Guru/Editor Instance Creator")]
|
||||||
|
private static void Init() => ((EditorInstanceCreator)GetWindow(typeof(EditorInstanceCreator))).Show();
|
||||||
|
|
||||||
|
private static void CreateProjectInstance(string projectInstanceName, bool includeProjectSettings,
|
||||||
|
string extraSubdirectories)
|
||||||
{
|
{
|
||||||
var targetDirectory = Path.Combine(Directory.GetCurrentDirectory(), ".." + Path.DirectorySeparatorChar, projectInstanceName);
|
string targetDirectory = Path.Combine(Directory.GetCurrentDirectory(), ".." + Path.DirectorySeparatorChar,
|
||||||
|
projectInstanceName);
|
||||||
Debug.Log(targetDirectory);
|
Debug.Log(targetDirectory);
|
||||||
if (Directory.Exists(targetDirectory))
|
if (Directory.Exists(targetDirectory))
|
||||||
{
|
{
|
||||||
@ -75,29 +71,21 @@ namespace TheGamedevGuru
|
|||||||
|
|
||||||
Directory.CreateDirectory(targetDirectory);
|
Directory.CreateDirectory(targetDirectory);
|
||||||
|
|
||||||
List<string> subdirectories = new List<string>{"Assets", "Packages"};
|
var subdirectories = new List<string> { "Assets", "Packages" };
|
||||||
if (includeProjectSettings)
|
if (includeProjectSettings) subdirectories.Add("ProjectSettings");
|
||||||
{
|
|
||||||
subdirectories.Add("ProjectSettings");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var extraSubdirectory in extraSubdirectories.Split(','))
|
foreach (string extraSubdirectory in extraSubdirectories.Split(','))
|
||||||
{
|
|
||||||
subdirectories.Add(extraSubdirectory.Trim());
|
subdirectories.Add(extraSubdirectory.Trim());
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var subdirectory in subdirectories)
|
foreach (string subdirectory in subdirectories)
|
||||||
{
|
Process.Start("CMD.exe", GetLinkCommand(subdirectory, targetDirectory));
|
||||||
System.Diagnostics.Process.Start("CMD.exe",GetLinkCommand(subdirectory, targetDirectory));
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorUtility.RevealInFinder(targetDirectory + Path.DirectorySeparatorChar + "Assets");
|
EditorUtility.RevealInFinder(targetDirectory + Path.DirectorySeparatorChar + "Assets");
|
||||||
EditorUtility.DisplayDialog("Done!", $"Done! Feel free to add it as an existing project at: {targetDirectory}", "Ok :)");
|
EditorUtility.DisplayDialog("Done!",
|
||||||
|
$"Done! Feel free to add it as an existing project at: {targetDirectory}", "Ok :)");
|
||||||
}
|
}
|
||||||
|
|
||||||
static string GetLinkCommand(string subdirectory, string targetDirectory)
|
private static string GetLinkCommand(string subdirectory, string targetDirectory) =>
|
||||||
{
|
$"/c mklink /J \"{targetDirectory}{Path.DirectorySeparatorChar}{subdirectory}\" \"{Directory.GetCurrentDirectory()}{Path.DirectorySeparatorChar}{subdirectory}\"";
|
||||||
return $"/c mklink /J \"{targetDirectory}{Path.DirectorySeparatorChar}{subdirectory}\" \"{Directory.GetCurrentDirectory()}{Path.DirectorySeparatorChar}{subdirectory}\"";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
42
Editor/EditorUtils.cs
Normal file
42
Editor/EditorUtils.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
|
namespace NegUtils.Editor
|
||||||
|
{
|
||||||
|
public class EditorUtils
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AssetPath
|
||||||
|
{
|
||||||
|
private readonly string filter;
|
||||||
|
|
||||||
|
private string path;
|
||||||
|
|
||||||
|
|
||||||
|
public AssetPath(string filter)
|
||||||
|
{
|
||||||
|
this.filter = filter;
|
||||||
|
TryFindPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Path
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (path != null)
|
||||||
|
return path;
|
||||||
|
TryFindPath();
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryFindPath()
|
||||||
|
{
|
||||||
|
string[] candidates = AssetDatabase.FindAssets(filter);
|
||||||
|
if (candidates.Length == 0)
|
||||||
|
throw new Exception("Missing layout asset!");
|
||||||
|
path = AssetDatabase.GUIDToAssetPath(candidates[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/EditorUtils.cs.meta
Normal file
3
Editor/EditorUtils.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a4848b69c1024df8ad6f76cfd4415d01
|
||||||
|
timeCreated: 1698258811
|
||||||
@ -3,15 +3,10 @@ using UnityEngine;
|
|||||||
|
|
||||||
public class GUIDToAssetPath : EditorWindow
|
public class GUIDToAssetPath : EditorWindow
|
||||||
{
|
{
|
||||||
string guid = "";
|
private string guid = "";
|
||||||
string path = "";
|
private string path = "";
|
||||||
[MenuItem("Tools/GUIDToAssetPath")]
|
|
||||||
static void CreateWindow()
|
|
||||||
{
|
|
||||||
GUIDToAssetPath window = (GUIDToAssetPath)EditorWindow.GetWindowWithRect(typeof(GUIDToAssetPath), new Rect(0, 0, 400, 120));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnGUI()
|
private void OnGUI()
|
||||||
{
|
{
|
||||||
GUILayout.Label("Enter guid");
|
GUILayout.Label("Enter guid");
|
||||||
guid = GUILayout.TextField(guid);
|
guid = GUILayout.TextField(guid);
|
||||||
@ -29,7 +24,14 @@ public class GUIDToAssetPath : EditorWindow
|
|||||||
GUILayout.EndHorizontal();
|
GUILayout.EndHorizontal();
|
||||||
GUILayout.Label(path);
|
GUILayout.Label(path);
|
||||||
}
|
}
|
||||||
static string GetAssetPath(string guid)
|
|
||||||
|
[MenuItem("Tools/GUIDToAssetPath")]
|
||||||
|
private static void CreateWindow()
|
||||||
|
{
|
||||||
|
var window = (GUIDToAssetPath)GetWindowWithRect(typeof(GUIDToAssetPath), new Rect(0, 0, 400, 120));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetAssetPath(string guid)
|
||||||
{
|
{
|
||||||
guid = guid.Replace("-", "");
|
guid = guid.Replace("-", "");
|
||||||
|
|
||||||
|
|||||||
46
Editor/MonoBehaviourExtensions.cs
Normal file
46
Editor/MonoBehaviourExtensions.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using System.IO;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Editor
|
||||||
|
{
|
||||||
|
public static class MonoBehaviourExtensions
|
||||||
|
{
|
||||||
|
[MenuItem("CONTEXT/MonoBehaviour/Change Script")]
|
||||||
|
public static void ChangeScript(MenuCommand command)
|
||||||
|
{
|
||||||
|
if (command.context == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var monoBehaviour = command.context as MonoBehaviour;
|
||||||
|
var monoScript = MonoScript.FromMonoBehaviour(monoBehaviour);
|
||||||
|
|
||||||
|
string scriptPath = AssetDatabase.GetAssetPath(monoScript);
|
||||||
|
string directoryPath = new FileInfo(scriptPath).Directory?.FullName;
|
||||||
|
|
||||||
|
// Allow the user to select which script to replace with
|
||||||
|
string newScriptPath = EditorUtility.OpenFilePanel("Select replacement script", directoryPath, "cs");
|
||||||
|
|
||||||
|
// Don't log anything if they cancelled the window
|
||||||
|
if (string.IsNullOrEmpty(newScriptPath)) return;
|
||||||
|
|
||||||
|
// Load the selected asset
|
||||||
|
string relativePath = "Assets\\" + Path.GetRelativePath(Application.dataPath, newScriptPath);
|
||||||
|
var chosenTextAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(relativePath);
|
||||||
|
|
||||||
|
if (chosenTextAsset == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Selected script couldn't be loaded ({relativePath})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Undo.RegisterCompleteObjectUndo(command.context, "Changing component script");
|
||||||
|
|
||||||
|
var so = new SerializedObject(monoBehaviour);
|
||||||
|
var scriptProperty = so.FindProperty("m_Script");
|
||||||
|
so.Update();
|
||||||
|
scriptProperty.objectReferenceValue = chosenTextAsset;
|
||||||
|
so.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/MonoBehaviourExtensions.cs.meta
Normal file
3
Editor/MonoBehaviourExtensions.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0501eedeaf1d4dcf8c4d0f1b7a0c1761
|
||||||
|
timeCreated: 1684519404
|
||||||
19
Editor/ReadOnlyAttributeDrawer.cs
Normal file
19
Editor/ReadOnlyAttributeDrawer.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Utils.Editor
|
||||||
|
{
|
||||||
|
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
|
||||||
|
public class ReadOnlyPropertyDrawer : PropertyDrawer
|
||||||
|
{
|
||||||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
GUI.enabled = false;
|
||||||
|
EditorGUI.PropertyField(position, property, label, true);
|
||||||
|
GUI.enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float GetPropertyHeight(SerializedProperty property, GUIContent label) =>
|
||||||
|
EditorGUI.GetPropertyHeight(property, label, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/ReadOnlyAttributeDrawer.cs.meta
Normal file
3
Editor/ReadOnlyAttributeDrawer.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1f837bac3a7b40528454a9fb9a46d0be
|
||||||
|
timeCreated: 1699371332
|
||||||
@ -1,5 +1,6 @@
|
|||||||
using UnityEngine;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Drawer for the RequireInterface attribute.
|
/// Drawer for the RequireInterface attribute.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -21,11 +22,12 @@ namespace NEG.Utils
|
|||||||
if (property.propertyType == SerializedPropertyType.ObjectReference)
|
if (property.propertyType == SerializedPropertyType.ObjectReference)
|
||||||
{
|
{
|
||||||
// Get attribute parameters.
|
// Get attribute parameters.
|
||||||
var requiredAttribute = this.attribute as RequireInterfaceAttribute;
|
var requiredAttribute = attribute as RequireInterfaceAttribute;
|
||||||
// Begin drawing property field.
|
// Begin drawing property field.
|
||||||
EditorGUI.BeginProperty(position, label, property);
|
EditorGUI.BeginProperty(position, label, property);
|
||||||
// Draw property field.
|
// Draw property field.
|
||||||
property.objectReferenceValue = EditorGUI.ObjectField(position, label, property.objectReferenceValue, requiredAttribute.requiredType, true);
|
property.objectReferenceValue = EditorGUI.ObjectField(position, label, property.objectReferenceValue,
|
||||||
|
requiredAttribute.requiredType, true);
|
||||||
// Finish drawing property field.
|
// Finish drawing property field.
|
||||||
EditorGUI.EndProperty();
|
EditorGUI.EndProperty();
|
||||||
}
|
}
|
||||||
|
|||||||
18
Editor/ScreenshotMaker.cs
Normal file
18
Editor/ScreenshotMaker.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.Editor
|
||||||
|
{
|
||||||
|
public static class ScreenshotMaker
|
||||||
|
{
|
||||||
|
[MenuItem("CONTEXT/Camera/Save view")]
|
||||||
|
public static void Capture(MenuCommand command)
|
||||||
|
{
|
||||||
|
string path = EditorUtility.SaveFilePanel("Save screenshot", "", "screen.png", "png");
|
||||||
|
if (path.Length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScreenCapture.CaptureScreenshot(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Editor/ScreenshotMaker.cs.meta
Normal file
3
Editor/ScreenshotMaker.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7dba407e8e8740a1bed3ee5fa833b13c
|
||||||
|
timeCreated: 1687881092
|
||||||
@ -1,21 +1,16 @@
|
|||||||
using System;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
|
|
||||||
namespace NEG.Utils.Serialization
|
namespace NEG.Utils.Serialization
|
||||||
{
|
{
|
||||||
public static class SerializationExtentions
|
public static class SerializationExtentions
|
||||||
{
|
{
|
||||||
public static SerializedProperty FindAutoProperty(this SerializedObject @this, string name)
|
public static SerializedProperty FindAutoProperty(this SerializedObject @this, string name) =>
|
||||||
{
|
@this.FindProperty(GetBackingFieldName(name));
|
||||||
return @this.FindProperty(GetBackingFieldName(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SerializedProperty FindAutoPropertyRelative(this SerializedProperty @this, string name)
|
public static SerializedProperty FindAutoPropertyRelative(this SerializedProperty @this, string name) =>
|
||||||
{
|
@this.FindPropertyRelative(GetBackingFieldName(name));
|
||||||
return @this.FindPropertyRelative(GetBackingFieldName(name));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string GetBackingFieldName(string name)
|
public static string GetBackingFieldName(string name)
|
||||||
{
|
{
|
||||||
#if NET_STANDARD || NET_STANDARD_2_1
|
#if NET_STANDARD || NET_STANDARD_2_1
|
||||||
return string.Create(1/*<*/ + name.Length + 16/*>k__BackingField*/, name, static (span, name) =>
|
return string.Create(1/*<*/ + name.Length + 16/*>k__BackingField*/, name, static (span, name) =>
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEditor.SceneManagement;
|
using UnityEditor.SceneManagement;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
@ -10,18 +9,13 @@ namespace NegUtils.Editor
|
|||||||
[InitializeOnLoad]
|
[InitializeOnLoad]
|
||||||
public class ToolsWindowBase : EditorWindow
|
public class ToolsWindowBase : EditorWindow
|
||||||
{
|
{
|
||||||
|
private const int UnitySceneExtensionLength = 6;
|
||||||
|
|
||||||
static ToolsWindowBase()
|
static ToolsWindowBase()
|
||||||
{
|
{
|
||||||
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
EditorApplication.playModeStateChanged += OnPlayModeStateChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MenuItem("Tools/Show Tools Window")]
|
|
||||||
private static void ShowWindow()
|
|
||||||
{
|
|
||||||
var window = GetWindow<ToolsWindowBase>();
|
|
||||||
window.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnGUI()
|
protected virtual void OnGUI()
|
||||||
{
|
{
|
||||||
if (GUILayout.Button("Select Scene"))
|
if (GUILayout.Button("Select Scene"))
|
||||||
@ -29,38 +23,58 @@ namespace NegUtils.Editor
|
|||||||
|
|
||||||
bool startFromSceneIndex0 = EditorPrefs.GetBool("StartFromSceneIndex0");
|
bool startFromSceneIndex0 = EditorPrefs.GetBool("StartFromSceneIndex0");
|
||||||
bool newVal = GUILayout.Toggle(startFromSceneIndex0, "Start from scene with index 0 on start");
|
bool newVal = GUILayout.Toggle(startFromSceneIndex0, "Start from scene with index 0 on start");
|
||||||
if (newVal != startFromSceneIndex0)
|
if (newVal != startFromSceneIndex0) EditorPrefs.SetBool("StartFromSceneIndex0", newVal);
|
||||||
{
|
|
||||||
EditorPrefs.SetBool("StartFromSceneIndex0", newVal);
|
if (!startFromSceneIndex0)
|
||||||
}
|
return;
|
||||||
|
|
||||||
if (startFromSceneIndex0)
|
|
||||||
{
|
|
||||||
bool goToCurrentScene = EditorPrefs.GetBool("GoToCurrentSceneAfterPlay");
|
bool goToCurrentScene = EditorPrefs.GetBool("GoToCurrentSceneAfterPlay");
|
||||||
newVal = GUILayout.Toggle(goToCurrentScene, "Go to current scene after play");
|
newVal = GUILayout.Toggle(goToCurrentScene, "Go to current scene after play");
|
||||||
if (newVal != goToCurrentScene)
|
if (newVal != goToCurrentScene) EditorPrefs.SetBool("GoToCurrentSceneAfterPlay", newVal);
|
||||||
|
|
||||||
|
bool goToFirstScene = EditorPrefs.GetBool("GoToFirstSceneAfterPlay");
|
||||||
|
newVal = GUILayout.Toggle(goToFirstScene, "Go to scene with index 1 after play");
|
||||||
|
if (newVal != goToFirstScene) EditorPrefs.SetBool("GoToFirstSceneAfterPlay", newVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MenuItem("Tools/Show Tools Window")]
|
||||||
|
private static void ShowWindow()
|
||||||
{
|
{
|
||||||
EditorPrefs.SetBool("GoToCurrentSceneAfterPlay", newVal);
|
var window = GetWindow<ToolsWindowBase>();
|
||||||
}
|
window.Show();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowScenesList(Rect position)
|
private static void ShowScenesList(Rect position)
|
||||||
{
|
{
|
||||||
var menu = new GenericMenu();
|
var menu = new GenericMenu();
|
||||||
|
|
||||||
string path = Application.dataPath + "/Scenes/Production";
|
string path = Application.dataPath + "/Scenes";
|
||||||
string[] fileInfo = Directory.GetFiles(path, "*.unity");
|
|
||||||
|
|
||||||
foreach (string item in fileInfo)
|
AddFiles(path, path, menu);
|
||||||
|
|
||||||
|
menu.DropDown(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void AddFiles(string path, string basePath, GenericMenu menu)
|
||||||
|
{
|
||||||
|
string[] fileInfo = Directory.GetFiles(path, "*.unity");
|
||||||
|
for (int i = 0; i < fileInfo.Length; i++)
|
||||||
|
{
|
||||||
|
string s = fileInfo[i];
|
||||||
|
menu.AddItem(
|
||||||
|
new GUIContent(s.Remove(0, basePath.Length + 1)
|
||||||
|
.Remove(s.Length - basePath.Length - UnitySceneExtensionLength - 1, UnitySceneExtensionLength)
|
||||||
|
.Replace('\\', '/')), false, () =>
|
||||||
{
|
{
|
||||||
string s = item;
|
|
||||||
menu.AddItem(new GUIContent(s.Remove(0, path.Length + 1).Remove(s.Length - path.Length - 7 ,6)), false, () => {
|
|
||||||
LoadScene(s);
|
LoadScene(s);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (i == fileInfo.Length) continue;
|
||||||
menu.AddSeparator("");
|
menu.AddSeparator("");
|
||||||
}
|
}
|
||||||
menu.DropDown(position);
|
|
||||||
|
string[] dirInfo = Directory.GetDirectories(path);
|
||||||
|
foreach (string dir in dirInfo) AddFiles(dir, basePath, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void LoadScene(string path)
|
private static void LoadScene(string path)
|
||||||
@ -88,9 +102,11 @@ namespace NegUtils.Editor
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (EditorPrefs.GetBool("GoToCurrentSceneAfterPlay"))
|
if (EditorPrefs.GetBool("GoToCurrentSceneAfterPlay"))
|
||||||
|
{
|
||||||
EditorSceneManager.LoadSceneInPlayMode(EditorPrefs.GetString("LastOpenedScenePath"),
|
EditorSceneManager.LoadSceneInPlayMode(EditorPrefs.GetString("LastOpenedScenePath"),
|
||||||
new LoadSceneParameters(LoadSceneMode.Single));
|
new LoadSceneParameters(LoadSceneMode.Single));
|
||||||
else
|
}
|
||||||
|
else if (EditorPrefs.GetBool("GoToFirstSceneAfterPlay"))
|
||||||
SceneManager.LoadScene(1);
|
SceneManager.LoadScene(1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -102,7 +118,6 @@ namespace NegUtils.Editor
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
14
Editor/TsvImporter.cs
Normal file
14
Editor/TsvImporter.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.IO;
|
||||||
|
using UnityEditor.AssetImporters;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[ScriptedImporter(1, "tsv")]
|
||||||
|
public class TsvImporter : ScriptedImporter
|
||||||
|
{
|
||||||
|
public override void OnImportAsset(AssetImportContext ctx)
|
||||||
|
{
|
||||||
|
var textAsset = new TextAsset(File.ReadAllText(ctx.assetPath));
|
||||||
|
ctx.AddObjectToAsset(Path.GetFileNameWithoutExtension(ctx.assetPath), textAsset);
|
||||||
|
ctx.SetMainObject(textAsset);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Editor/TsvImporter.cs.meta
Normal file
11
Editor/TsvImporter.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b3f8438db4084014bab0a063e4675d3f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
50
KeyBasedFactory.cs
Normal file
50
KeyBasedFactory.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
using JetBrains.Annotations;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace NEG.Utils
|
||||||
|
{
|
||||||
|
public class KeyBasedFactory<T1, T2>
|
||||||
|
{
|
||||||
|
[PublicAPI] protected Dictionary<T1, Type> data;
|
||||||
|
|
||||||
|
public KeyBasedFactory()
|
||||||
|
{
|
||||||
|
data = new Dictionary<T1, Type>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void FireRegistration()
|
||||||
|
{
|
||||||
|
ScanAssembly(typeof(T2).Assembly);
|
||||||
|
|
||||||
|
if (typeof(T2).Assembly.GetType().Assembly == typeof(T2).Assembly)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ScanAssembly(typeof(T2).Assembly.GetType().Assembly);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ScanAssembly(Assembly assembly)
|
||||||
|
{
|
||||||
|
foreach (var type in assembly.GetTypes())
|
||||||
|
{
|
||||||
|
var methodFields =
|
||||||
|
type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
for (int i = 0; i < methodFields.Length; i++)
|
||||||
|
{
|
||||||
|
if (Attribute.GetCustomAttribute(methodFields[i], typeof(FactoryRegistration)) != null)
|
||||||
|
methodFields[i].Invoke(null, Array.Empty<object>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Register(T1 key, Type type) => data.Add(key, type);
|
||||||
|
|
||||||
|
public T2 CreateInstance(T1 key, params object[] args) => (T2)Activator.CreateInstance(data[key], args);
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public class FactoryRegistration : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
3
KeyBasedFactory.cs.meta
Normal file
3
KeyBasedFactory.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e0d3df1ddd34209bfb7262b4e51abfe
|
||||||
|
timeCreated: 1683917310
|
||||||
@ -1,9 +1,11 @@
|
|||||||
using NEG.UI.WindowSlot;
|
using NEG.UI.WindowSlot;
|
||||||
|
using NegUtils.NEG.UI;
|
||||||
|
|
||||||
namespace NEG.UI.Area
|
namespace NEG.UI.Area
|
||||||
{
|
{
|
||||||
public interface IArea : ISlotsHolder, IUiElement
|
public interface IArea : ISlotsHolder, IControllable
|
||||||
{
|
{
|
||||||
|
void Open();
|
||||||
|
void Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
18
NEG/UI/IControllable.cs
Normal file
18
NEG/UI/IControllable.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NegUtils.NEG.UI
|
||||||
|
{
|
||||||
|
public interface IControllable
|
||||||
|
{
|
||||||
|
event Action<object> OnOpened;
|
||||||
|
event Action OnClosed;
|
||||||
|
event Action<BackUsed> OnBackUsed;
|
||||||
|
|
||||||
|
public void TryUseBack(ref BackUsed backUsed);
|
||||||
|
|
||||||
|
public class BackUsed
|
||||||
|
{
|
||||||
|
public bool Used { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/IControllable.cs.meta
Normal file
3
NEG/UI/IControllable.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 175798310e4048eda768cf40e6ee6de3
|
||||||
|
timeCreated: 1686596400
|
||||||
7
NEG/UI/IController.cs
Normal file
7
NEG/UI/IController.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace NegUtils.NEG.UI
|
||||||
|
{
|
||||||
|
public interface IController
|
||||||
|
{
|
||||||
|
IControllable Controllable { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/IController.cs.meta
Normal file
3
NEG/UI/IController.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b88f4a93020a4bc6bde40e0438d296a9
|
||||||
|
timeCreated: 1686595825
|
||||||
@ -1,11 +0,0 @@
|
|||||||
namespace NEG.UI
|
|
||||||
{
|
|
||||||
public interface IUiElement
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Sets only visible state of element
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="setEnabled"></param>
|
|
||||||
void SetEnabled(bool setEnabled);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 296bf6969a6347f8aea788a7bdd086af
|
|
||||||
timeCreated: 1670693177
|
|
||||||
@ -1,7 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "NEG.UI",
|
"name": "NEG.UI",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [],
|
"references": [
|
||||||
|
"GUID:3c4294719a93e3c4e831a9ff0c261e8a"
|
||||||
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
"allowUnsafeCode": false,
|
"allowUnsafeCode": false,
|
||||||
|
|||||||
@ -5,13 +5,14 @@ namespace NEG.UI.Popup
|
|||||||
{
|
{
|
||||||
public class DefaultPopupData : PopupData
|
public class DefaultPopupData : PopupData
|
||||||
{
|
{
|
||||||
private readonly IDefaultPopup defaultPopup;
|
|
||||||
|
|
||||||
private readonly string title;
|
|
||||||
private readonly string content;
|
private readonly string content;
|
||||||
|
private readonly IDefaultPopup defaultPopup;
|
||||||
private readonly List<(string, Action)> options;
|
private readonly List<(string, Action)> options;
|
||||||
|
|
||||||
public DefaultPopupData(IDefaultPopup popup, string title, string content, List<(string, Action)> options) : base(popup)
|
private readonly string title;
|
||||||
|
|
||||||
|
public DefaultPopupData(IDefaultPopup popup, string title, string content, List<(string, Action)> options) :
|
||||||
|
base(popup)
|
||||||
{
|
{
|
||||||
defaultPopup = popup;
|
defaultPopup = popup;
|
||||||
this.title = title;
|
this.title = title;
|
||||||
|
|||||||
@ -10,7 +10,10 @@ namespace NEG.UI.Popup
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">popup title</param>
|
/// <param name="title">popup title</param>
|
||||||
/// <param name="content">popup content</param>
|
/// <param name="content">popup content</param>
|
||||||
/// <param name="options">list of tuples (name, action on click), to set buttons. Do not pass here popup closing logic, implementing class should do it</param>
|
/// <param name="options">
|
||||||
|
/// list of tuples (name, action on click), to set buttons. Do not pass here popup closing logic,
|
||||||
|
/// implementing class should do it
|
||||||
|
/// </param>
|
||||||
public void SetContent(string title, string content, List<(string name, Action action)> options);
|
public void SetContent(string title, string content, List<(string name, Action action)> options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -6,20 +6,6 @@ namespace NEG.UI.Popup
|
|||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public class PopupData
|
public class PopupData
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// Event that is fired on closing popup.
|
|
||||||
/// </summary>
|
|
||||||
public event Action<PopupData> PopupClosedEvent
|
|
||||||
{
|
|
||||||
add => popup.OnPopupClosed += value;
|
|
||||||
remove => popup.OnPopupClosed -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Is this data is still valid. If set to false, popup will not show.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsValid { get; protected set; }
|
|
||||||
|
|
||||||
private readonly IPopup popup;
|
private readonly IPopup popup;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -32,6 +18,20 @@ namespace NEG.UI.Popup
|
|||||||
IsValid = true;
|
IsValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this data is still valid. If set to false, popup will not show.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsValid { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Event that is fired on closing popup.
|
||||||
|
/// </summary>
|
||||||
|
public event Action<PopupData> PopupClosedEvent
|
||||||
|
{
|
||||||
|
add => popup.OnPopupClosed += value;
|
||||||
|
remove => popup.OnPopupClosed -= value;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show popup and pass needed data.
|
/// Show popup and pass needed data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -45,6 +45,10 @@ namespace NEG.UI.Popup
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invalidate popup, <see cref="UiManager" /> will automatically skip this popup
|
/// Invalidate popup, <see cref="UiManager" /> will automatically skip this popup
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Invalidate() => IsValid = false;
|
public virtual void Invalidate()
|
||||||
|
{
|
||||||
|
IsValid = false;
|
||||||
|
UiManager.Instance.RefreshPopups();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,8 +248,10 @@ namespace System.Collections.Generic
|
|||||||
public PriorityQueue(int initialCapacity, IComparer<TPriority>? comparer)
|
public PriorityQueue(int initialCapacity, IComparer<TPriority>? comparer)
|
||||||
{
|
{
|
||||||
if (initialCapacity < 0)
|
if (initialCapacity < 0)
|
||||||
|
{
|
||||||
throw new ArgumentOutOfRangeException(
|
throw new ArgumentOutOfRangeException(
|
||||||
nameof(initialCapacity), initialCapacity, SR.ArgumentOutOfRange_NeedNonNegNum);
|
nameof(initialCapacity), initialCapacity, SR.ArgumentOutOfRange_NeedNonNegNum);
|
||||||
|
}
|
||||||
|
|
||||||
_nodes = new (TElement, TPriority)[initialCapacity];
|
_nodes = new (TElement, TPriority)[initialCapacity];
|
||||||
_comparer = InitializeComparer(comparer);
|
_comparer = InitializeComparer(comparer);
|
||||||
@ -489,7 +491,7 @@ namespace System.Collections.Generic
|
|||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
(TElement, TPriority)[] nodes = _nodes;
|
(TElement, TPriority)[] nodes = _nodes;
|
||||||
foreach ((var element, var priority) in items)
|
foreach (var (element, priority) in items)
|
||||||
{
|
{
|
||||||
if (nodes.Length == i)
|
if (nodes.Length == i)
|
||||||
{
|
{
|
||||||
@ -508,9 +510,8 @@ namespace System.Collections.Generic
|
|||||||
if (_size > 1) Heapify();
|
if (_size > 1) Heapify();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
foreach (var (element, priority) in items)
|
||||||
foreach ((var element, var priority) in items) Enqueue(element, priority);
|
Enqueue(element, priority);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -554,9 +555,8 @@ namespace System.Collections.Generic
|
|||||||
if (i > 1) Heapify();
|
if (i > 1) Heapify();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
foreach (var element in elements)
|
||||||
foreach (var element in elements) Enqueue(element, priority);
|
Enqueue(element, priority);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -684,12 +684,16 @@ namespace System.Collections.Generic
|
|||||||
int lastParentWithChildren = GetParentIndex(_size - 1);
|
int lastParentWithChildren = GetParentIndex(_size - 1);
|
||||||
|
|
||||||
if (_comparer == null)
|
if (_comparer == null)
|
||||||
|
{
|
||||||
for (int index = lastParentWithChildren; index >= 0; --index)
|
for (int index = lastParentWithChildren; index >= 0; --index)
|
||||||
MoveDownDefaultComparer(nodes[index], index);
|
MoveDownDefaultComparer(nodes[index], index);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
for (int index = lastParentWithChildren; index >= 0; --index)
|
for (int index = lastParentWithChildren; index >= 0; --index)
|
||||||
MoveDownCustomComparer(nodes[index], index);
|
MoveDownCustomComparer(nodes[index], index);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Moves a node up in the tree to restore heap order.
|
/// Moves a node up in the tree to restore heap order.
|
||||||
@ -715,10 +719,8 @@ namespace System.Collections.Generic
|
|||||||
nodeIndex = parentIndex;
|
nodeIndex = parentIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nodes[nodeIndex] = node;
|
nodes[nodeIndex] = node;
|
||||||
}
|
}
|
||||||
@ -748,10 +750,8 @@ namespace System.Collections.Generic
|
|||||||
nodeIndex = parentIndex;
|
nodeIndex = parentIndex;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
nodes[nodeIndex] = node;
|
nodes[nodeIndex] = node;
|
||||||
}
|
}
|
||||||
@ -894,8 +894,10 @@ namespace System.Collections.Generic
|
|||||||
if (array.GetLowerBound(0) != 0) throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array));
|
if (array.GetLowerBound(0) != 0) throw new ArgumentException(SR.Arg_NonZeroLowerBound, nameof(array));
|
||||||
|
|
||||||
if (index < 0 || index > array.Length)
|
if (index < 0 || index > array.Length)
|
||||||
|
{
|
||||||
throw new ArgumentOutOfRangeException(nameof(index), index,
|
throw new ArgumentOutOfRangeException(nameof(index), index,
|
||||||
SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
|
SR.ArgumentOutOfRange_IndexMustBeLessOrEqual);
|
||||||
|
}
|
||||||
|
|
||||||
if (array.Length - index < _queue._size) throw new ArgumentException(SR.Argument_InvalidOffLen);
|
if (array.Length - index < _queue._size) throw new ArgumentException(SR.Argument_InvalidOffLen);
|
||||||
|
|
||||||
|
|||||||
@ -2,47 +2,28 @@ using JetBrains.Annotations;
|
|||||||
using NEG.UI.Area;
|
using NEG.UI.Area;
|
||||||
using NEG.UI.Popup;
|
using NEG.UI.Popup;
|
||||||
using NEG.UI.Window;
|
using NEG.UI.Window;
|
||||||
|
using NegUtils.NEG.UI;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.UI
|
namespace NEG.UI
|
||||||
{
|
{
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public abstract class UiManager
|
public abstract class UiManager : IDisposable
|
||||||
{
|
{
|
||||||
public static UiManager Instance { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Current area shown on screen.
|
|
||||||
/// </summary>
|
|
||||||
public IArea CurrentArea
|
|
||||||
{
|
|
||||||
get => currentArea;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
currentArea?.SetEnabled(false);
|
|
||||||
|
|
||||||
currentArea = value;
|
|
||||||
|
|
||||||
currentArea?.SetEnabled(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Current window that is considered main (focused, lastly opened). Can be null.
|
|
||||||
/// </summary>
|
|
||||||
public IWindow CurrentMainWindow { get; protected set; }
|
|
||||||
|
|
||||||
private IArea currentArea;
|
private IArea currentArea;
|
||||||
private (PopupData data, int priority) currentShownPopup;
|
|
||||||
protected IDefaultPopup currentDefaultPopup;
|
protected IDefaultPopup currentDefaultPopup;
|
||||||
|
private (PopupData data, int priority) currentShownPopup;
|
||||||
private PriorityQueue<PopupData, int> popupsToShow = new();
|
|
||||||
|
|
||||||
//TODO: localize
|
//TODO: localize
|
||||||
private string localizedYes = "Yes", localizedNo = "No", localizedOk = "Ok";
|
private string localizedYes = "Yes", localizedNo = "No", localizedOk = "Ok";
|
||||||
|
|
||||||
|
private List<IWindow> mainWindows;
|
||||||
|
|
||||||
|
private PriorityQueue<PopupData, int> popupsToShow = new();
|
||||||
|
|
||||||
protected UiManager(IArea startArea)
|
protected UiManager(IArea startArea)
|
||||||
{
|
{
|
||||||
if (Instance != null)
|
if (Instance != null)
|
||||||
@ -54,10 +35,39 @@ namespace NEG.UI
|
|||||||
Instance = this;
|
Instance = this;
|
||||||
|
|
||||||
CurrentArea = startArea;
|
CurrentArea = startArea;
|
||||||
|
mainWindows = new List<IWindow>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UiManager Instance { get; protected set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Current area shown on screen.
|
||||||
|
/// </summary>
|
||||||
|
public IArea CurrentArea
|
||||||
|
{
|
||||||
|
get => currentArea;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
currentArea?.Close();
|
||||||
|
|
||||||
|
currentArea = value;
|
||||||
|
|
||||||
|
currentArea?.Open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing ok button.
|
/// Current window that is considered main (focused, lastly opened). Can be null.
|
||||||
|
/// </summary>
|
||||||
|
public IWindow CurrentMainWindow => mainWindows.LastOrDefault();
|
||||||
|
|
||||||
|
public PopupData CurrentPopup => currentShownPopup.data;
|
||||||
|
|
||||||
|
public virtual void Dispose() => Instance = null;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later.
|
||||||
|
/// It will be closed after pressing ok button.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">popup title</param>
|
/// <param name="title">popup title</param>
|
||||||
/// <param name="content">popup content</param>
|
/// <param name="content">popup content</param>
|
||||||
@ -66,16 +76,18 @@ namespace NEG.UI
|
|||||||
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
||||||
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
||||||
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
||||||
public PopupData ShowOkPopup(string title, string content, string okText = null, Action okPressed = null, int priority = 0, bool forceShow = false)
|
public PopupData ShowOkPopup(string title, string content, string okText = null, Action okPressed = null,
|
||||||
|
int priority = 0, bool forceShow = false)
|
||||||
{
|
{
|
||||||
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
||||||
new List<(string, Action)>() { (okText ?? localizedOk, okPressed) });
|
new List<(string, Action)> { (okText ?? localizedOk, okPressed) });
|
||||||
ShowPopup(data, priority, forceShow);
|
ShowPopup(data, priority, forceShow);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing yes or no button.
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later.
|
||||||
|
/// It will be closed after pressing yes or no button.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">popup title</param>
|
/// <param name="title">popup title</param>
|
||||||
/// <param name="content">popup content</param>
|
/// <param name="content">popup content</param>
|
||||||
@ -86,16 +98,21 @@ namespace NEG.UI
|
|||||||
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
||||||
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
||||||
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
||||||
public PopupData ShowYesNoPopup(string title, string content, string yesText = null, string noText = null, Action yesPressed = null, Action noPressed = null, int priority = 0, bool forceShow = false)
|
public PopupData ShowYesNoPopup(string title, string content, string yesText = null, string noText = null,
|
||||||
|
Action yesPressed = null, Action noPressed = null, int priority = 0, bool forceShow = false)
|
||||||
{
|
{
|
||||||
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
var data = new DefaultPopupData(currentDefaultPopup, title, content,
|
||||||
new List<(string, Action)>() { (yesText ?? localizedYes, yesPressed), (noText ?? localizedNo, noPressed) });
|
new List<(string, Action)>
|
||||||
|
{
|
||||||
|
(yesText ?? localizedYes, yesPressed), (noText ?? localizedNo, noPressed)
|
||||||
|
});
|
||||||
ShowPopup(data, priority, forceShow);
|
ShowPopup(data, priority, forceShow);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later. It will be closed after pressing any button.
|
/// Show popup if there is non other currently shown. Otherwise add current popup to ordered queue and show it later.
|
||||||
|
/// It will be closed after pressing any button.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="title">popup title</param>
|
/// <param name="title">popup title</param>
|
||||||
/// <param name="content">popup content</param>
|
/// <param name="content">popup content</param>
|
||||||
@ -103,7 +120,8 @@ namespace NEG.UI
|
|||||||
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
/// <param name="priority">priority of popup (lower number -> show first)</param>
|
||||||
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
/// <param name="forceShow">force show current popup only if currently shown has lower priority</param>
|
||||||
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
/// <returns>data for created popup, can be used to invalidate popup (will not show)</returns>
|
||||||
public PopupData ShowPopup(string title, string content, List<(string, Action)> actions, int priority = 0, bool forceShow = false)
|
public PopupData ShowPopup(string title, string content, List<(string, Action)> actions, int priority = 0,
|
||||||
|
bool forceShow = false)
|
||||||
{
|
{
|
||||||
var data = new DefaultPopupData(currentDefaultPopup, title, content, actions);
|
var data = new DefaultPopupData(currentDefaultPopup, title, content, actions);
|
||||||
ShowPopup(data, priority, forceShow);
|
ShowPopup(data, priority, forceShow);
|
||||||
@ -122,23 +140,47 @@ namespace NEG.UI
|
|||||||
UpdatePopupsState(forceShow, priority, data);
|
UpdatePopupsState(forceShow, priority, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UseBack()
|
||||||
|
{
|
||||||
|
IControllable.BackUsed backUsed = new();
|
||||||
|
|
||||||
|
CurrentMainWindow?.TryUseBack(ref backUsed);
|
||||||
|
if (backUsed.Used)
|
||||||
|
return;
|
||||||
|
CurrentArea.TryUseBack(ref backUsed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void RefreshPopups()
|
||||||
|
{
|
||||||
|
if (currentShownPopup.data is { IsValid: true })
|
||||||
|
return;
|
||||||
|
UpdatePopupsState(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetMainWindow(IWindow window) => mainWindows.Add(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)
|
protected void PopupClosed(PopupData data)
|
||||||
{
|
{
|
||||||
if (currentShownPopup.data != data)
|
if (currentShownPopup.data != data)
|
||||||
{
|
//Debug.LogError("Popup was not shown");
|
||||||
Debug.LogError("Popup was not shown");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
UpdatePopupsState(false);
|
UpdatePopupsState(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void SetDefaultPopup(IDefaultPopup popup) => currentDefaultPopup = popup;
|
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)
|
if (forceShow)
|
||||||
{
|
{
|
||||||
if(currentShownPopup.priority <= priority)
|
if (currentShownPopup.data != null && currentShownPopup.priority >= priority)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
popupsToShow.Enqueue(currentShownPopup.data, currentShownPopup.priority);
|
popupsToShow.Enqueue(currentShownPopup.data, currentShownPopup.priority);
|
||||||
@ -146,10 +188,23 @@ namespace NEG.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!popupsToShow.TryDequeue(out var d, out int p))
|
while (popupsToShow.TryDequeue(out var d, out int p))
|
||||||
return;
|
{
|
||||||
|
if (d == null)
|
||||||
|
continue;
|
||||||
|
if (!d.IsValid)
|
||||||
|
continue;
|
||||||
|
if (d == currentShownPopup.data)
|
||||||
|
continue;
|
||||||
ShowPopup(d, p);
|
ShowPopup(d, p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentShownPopup.data == null)
|
||||||
|
return;
|
||||||
|
currentShownPopup.data.PopupClosedEvent -= PopupClosed;
|
||||||
|
currentShownPopup.data.Hide();
|
||||||
|
currentShownPopup.data = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowPopup(PopupData data, int priority)
|
private void ShowPopup(PopupData data, int priority)
|
||||||
@ -159,11 +214,10 @@ namespace NEG.UI
|
|||||||
currentShownPopup.data.PopupClosedEvent -= PopupClosed;
|
currentShownPopup.data.PopupClosedEvent -= PopupClosed;
|
||||||
currentShownPopup.data.Hide();
|
currentShownPopup.data.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
currentShownPopup = (data, priority);
|
currentShownPopup = (data, priority);
|
||||||
data.Show();
|
data.Show();
|
||||||
data.PopupClosedEvent += PopupClosed;
|
data.PopupClosedEvent += PopupClosed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
17
NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs
Normal file
17
NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs.meta
Normal file
3
NEG/UI/UnityUi/Area/AutoOpenWindowWhenNoOther.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 473c065573984067a824ebf3b605c3ab
|
||||||
|
timeCreated: 1695048071
|
||||||
@ -1,11 +1,10 @@
|
|||||||
using NEG.UI.UnityUi.Window;
|
using NEG.UI.UnityUi.Window;
|
||||||
using NEG.UI.Window;
|
using NEG.UI.Window;
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.UI.Area
|
namespace NEG.UI.Area
|
||||||
{
|
{
|
||||||
[Tooltip(tooltip: "Automatically open attached window on start")]
|
[Tooltip("Automatically open attached window on start")]
|
||||||
public class AutoWindowOpen : MonoBehaviour
|
public class AutoWindowOpen : MonoBehaviour
|
||||||
{
|
{
|
||||||
[SerializeField] private MonoWindow window;
|
[SerializeField] private MonoWindow window;
|
||||||
|
|||||||
16
NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs
Normal file
16
NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using NEG.UI.UnityUi;
|
||||||
|
using NEG.UI.Window;
|
||||||
|
using NegUtils.NEG.UI;
|
||||||
|
|
||||||
|
namespace NEG.UI.Area
|
||||||
|
{
|
||||||
|
public class CloseMainWindowOnBack : MonoController
|
||||||
|
{
|
||||||
|
protected override void OnBackUsed(IControllable.BackUsed backUsed)
|
||||||
|
{
|
||||||
|
base.OnBackUsed(backUsed);
|
||||||
|
UiManager.Instance.CurrentMainWindow?.Close();
|
||||||
|
backUsed.Used = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs.meta
Normal file
3
NEG/UI/UnityUi/Area/CloseMainWindowOnBack.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 6ec2bf64cda740a1849d024d4f163a01
|
||||||
|
timeCreated: 1686598066
|
||||||
@ -1,30 +1,19 @@
|
|||||||
using System.Collections.Generic;
|
using NEG.UI.UnityUi.WindowSlot;
|
||||||
using UnityEngine;
|
|
||||||
using NEG.UI.Popup;
|
|
||||||
using NEG.UI.UnityUi.Window;
|
|
||||||
using NEG.UI.UnityUi.WindowSlot;
|
|
||||||
using NEG.UI.Window;
|
using NEG.UI.Window;
|
||||||
using NEG.UI.WindowSlot;
|
using NEG.UI.WindowSlot;
|
||||||
|
using NegUtils.NEG.UI;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.UI.Area
|
namespace NEG.UI.Area
|
||||||
{
|
{
|
||||||
public class MonoArea : MonoBehaviour, IArea
|
public class MonoArea : MonoBehaviour, IArea
|
||||||
{
|
{
|
||||||
public IEnumerable<IWindowSlot> AvailableSlots => windowSlots;
|
|
||||||
public IWindowSlot DefaultWindowSlot => windowSlots[0];
|
|
||||||
|
|
||||||
[SerializeField] private bool setAsDefaultArea;
|
[SerializeField] private bool setAsDefaultArea;
|
||||||
|
|
||||||
[SerializeField] private List<MonoWindowSlot> windowSlots;
|
[SerializeField] private List<MonoWindowSlot> windowSlots;
|
||||||
|
public IWindowSlot DefaultWindowSlot => windowSlots[0];
|
||||||
public virtual void SetEnabled(bool setEnabled) => gameObject.SetActive(setEnabled);
|
|
||||||
|
|
||||||
public virtual void OpenWindow(IWindow window, object data = null)
|
|
||||||
{
|
|
||||||
DefaultWindowSlot.AttachWindow(window);
|
|
||||||
window.SetData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Awake()
|
protected virtual void Awake()
|
||||||
{
|
{
|
||||||
@ -32,10 +21,40 @@ namespace NEG.UI.Area
|
|||||||
UiManager.Instance.CurrentArea = this;
|
UiManager.Instance.CurrentArea = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnDestroy()
|
private void Start()
|
||||||
{
|
{
|
||||||
|
if (!setAsDefaultArea)
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
if (UiManager.Instance == null)
|
||||||
|
return;
|
||||||
if (ReferenceEquals(UiManager.Instance.CurrentArea, this))
|
if (ReferenceEquals(UiManager.Instance.CurrentArea, this))
|
||||||
UiManager.Instance.CurrentArea = null;
|
UiManager.Instance.CurrentArea = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public event Action<object> OnOpened;
|
||||||
|
public event Action OnClosed;
|
||||||
|
public event Action<IControllable.BackUsed> OnBackUsed;
|
||||||
|
|
||||||
|
public IEnumerable<IWindowSlot> AvailableSlots => windowSlots;
|
||||||
|
|
||||||
|
public void Open()
|
||||||
|
{
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
OnOpened?.Invoke(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Close()
|
||||||
|
{
|
||||||
|
gameObject.SetActive(false);
|
||||||
|
OnClosed?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenWindow(IWindow window, object data = null) => DefaultWindowSlot.AttachWindow(window, data);
|
||||||
|
|
||||||
|
public void TryUseBack(ref IControllable.BackUsed backUsed) => OnBackUsed?.Invoke(backUsed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,3 +1,11 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 39eb59ca1ef60934abb3f0c64169be65
|
guid: 39eb59ca1ef60934abb3f0c64169be65
|
||||||
timeCreated: 1670707479
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 10
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|||||||
@ -1,77 +1,103 @@
|
|||||||
using FMOD.Studio;
|
using KBCore.Refs;
|
||||||
using FMODUnity;
|
using NEG.UI.UnityUi.Buttons.Behaviours;
|
||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.EventSystems;
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
namespace NEG.UI.UnityUi.Buttons
|
||||||
{
|
{
|
||||||
[RequireComponent(typeof(ButtonSerializeFields))]
|
[DefaultExecutionOrder(-1)]
|
||||||
|
[RequireComponent(typeof(Button))]
|
||||||
public class BaseButton : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler
|
public class BaseButton : MonoBehaviour, ISelectHandler, IDeselectHandler, IPointerEnterHandler, IPointerExitHandler
|
||||||
{
|
{
|
||||||
public event Action OnButtonPressed;
|
public delegate void SelectionHandler(bool isSilent);
|
||||||
|
|
||||||
public bool Interactable { get => serializeFields.Button.interactable; set => serializeFields.Button.interactable = value; }
|
[SerializeField] [Self(Flag.Optional)] private Button button;
|
||||||
|
|
||||||
[SerializeField]
|
[SerializeField] [Child(Flag.Optional)]
|
||||||
protected ButtonSerializeFields serializeFields;
|
private TMP_Text text;
|
||||||
|
|
||||||
private bool isHovered;
|
[SerializeField] [Child(Flag.Optional)]
|
||||||
|
private Image icon;
|
||||||
|
|
||||||
public virtual void OnSelect(BaseEventData eventData)
|
[SerializeField] private ButtonSettings groupButtonSettings;
|
||||||
{
|
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.SelectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnDeselect(BaseEventData eventData)
|
private readonly Dictionary<string, ButtonElementBehaviour> behaviours = new();
|
||||||
{
|
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.DeselectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPointerEnter(PointerEventData eventData)
|
public bool Interactable { get => button.interactable; set => button.interactable = value; }
|
||||||
{
|
|
||||||
isHovered = true;
|
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.SelectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPointerExit(PointerEventData eventData)
|
public TMP_Text Text => text;
|
||||||
{
|
|
||||||
isHovered = false;
|
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.DeselectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetText(string text)
|
|
||||||
{
|
|
||||||
if(serializeFields == null)
|
|
||||||
return;
|
|
||||||
if(serializeFields.Text == null)
|
|
||||||
return;
|
|
||||||
serializeFields.Text.text = text;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void Awake()
|
protected virtual void Awake()
|
||||||
{
|
{
|
||||||
if(serializeFields == null)
|
button.onClick.AddListener(OnClicked);
|
||||||
serializeFields = GetComponent<ButtonSerializeFields>();
|
if (groupButtonSettings == null)
|
||||||
serializeFields.Button.onClick.AddListener(OnClicked);
|
MonoUiManager.Instance.DefaultUiSettings.Apply(this);
|
||||||
OnDeselect(null);
|
else
|
||||||
|
groupButtonSettings.Apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValidate()
|
private void Start() => OnDeselect(null);
|
||||||
|
|
||||||
|
private void OnValidate() => this.ValidateRefs();
|
||||||
|
|
||||||
|
public void OnDeselect(BaseEventData eventData) => OnDeselected?.Invoke(eventData is SilentEventData);
|
||||||
|
|
||||||
|
public void OnPointerEnter(PointerEventData eventData) => EventSystem.current.SetSelectedGameObject(gameObject);
|
||||||
|
|
||||||
|
public void OnPointerExit(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
if(serializeFields == null)
|
if (EventSystem.current.currentSelectedGameObject == gameObject)
|
||||||
serializeFields = GetComponent<ButtonSerializeFields>();
|
EventSystem.current.SetSelectedGameObject(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnSelect(BaseEventData eventData) => OnSelected?.Invoke(eventData is SilentEventData);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// is silent
|
||||||
|
/// </summary>
|
||||||
|
public event SelectionHandler OnSelected;
|
||||||
|
|
||||||
|
public event SelectionHandler OnDeselected;
|
||||||
|
public event Action OnButtonPressed;
|
||||||
|
|
||||||
|
public void SetText(string txt)
|
||||||
|
{
|
||||||
|
if (text == null)
|
||||||
|
return;
|
||||||
|
text.text = txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOrOverrideSetting(SettingData data)
|
||||||
|
{
|
||||||
|
if (behaviours.TryGetValue(data.Key, out var setting))
|
||||||
|
{
|
||||||
|
setting.ChangeData(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
behaviours.Add(data.Key, MonoUiManager.Instance.BehavioursFactory.CreateInstance(data.Key, this, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSetting(string key)
|
||||||
|
{
|
||||||
|
if (!behaviours.TryGetValue(key, out var setting))
|
||||||
|
{
|
||||||
|
Debug.LogError($"Behaviour with key {key} was not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setting.Dispose();
|
||||||
|
behaviours.Remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void OnClicked()
|
protected virtual void OnClicked()
|
||||||
{
|
{
|
||||||
OnDeselect(null);
|
OnDeselect(null);
|
||||||
isHovered = false;
|
|
||||||
OnButtonPressed?.Invoke();
|
OnButtonPressed?.Invoke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,11 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 3a250ef2d0c34e7396a16fc5eddbdb01
|
guid: 3a250ef2d0c34e7396a16fc5eddbdb01
|
||||||
timeCreated: 1670777213
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: -1
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
|
|||||||
3
NEG/UI/UnityUi/Buttons/Behaviours.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Behaviours.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 953c3353e3af44258625fe607ede632b
|
||||||
|
timeCreated: 1683915598
|
||||||
21
NEG/UI/UnityUi/Buttons/Behaviours/ButtonElementBehaviour.cs
Normal file
21
NEG/UI/UnityUi/Buttons/Behaviours/ButtonElementBehaviour.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Behaviours
|
||||||
|
{
|
||||||
|
public abstract class ButtonElementBehaviour : IDisposable
|
||||||
|
{
|
||||||
|
protected readonly BaseButton button;
|
||||||
|
protected SettingData baseData;
|
||||||
|
|
||||||
|
public ButtonElementBehaviour(BaseButton baseButton, SettingData settingData)
|
||||||
|
{
|
||||||
|
button = baseButton;
|
||||||
|
baseData = settingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void Dispose();
|
||||||
|
|
||||||
|
public virtual void ChangeData(SettingData newData) => baseData = newData;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a5e3decad6424cb288eff3e6f7e0d28e
|
||||||
|
timeCreated: 1683919740
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
|
using NEG.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Behaviours
|
||||||
|
{
|
||||||
|
public class ChangeTextColorBehaviour : ButtonElementBehaviour
|
||||||
|
{
|
||||||
|
private ColorData data;
|
||||||
|
|
||||||
|
public ChangeTextColorBehaviour(BaseButton baseButton, ColorData data) : base(baseButton, data)
|
||||||
|
{
|
||||||
|
if (baseButton.Text == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
baseButton.OnSelected += OnButtonSelected;
|
||||||
|
baseButton.OnDeselected += OnButtonDeselected;
|
||||||
|
ChangeData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ChangeData(SettingData newData)
|
||||||
|
{
|
||||||
|
base.ChangeData(newData);
|
||||||
|
Debug.Assert(newData is ColorData, "newData is not ColorData");
|
||||||
|
data = (ColorData)newData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
button.OnSelected -= OnButtonSelected;
|
||||||
|
button.OnDeselected -= OnButtonDeselected;
|
||||||
|
}
|
||||||
|
|
||||||
|
[FactoryRegistration]
|
||||||
|
private static void RegisterInFactory() =>
|
||||||
|
MonoUiManager.Instance.BehavioursFactory.Register("ChangeTextColor", typeof(ChangeTextColorBehaviour));
|
||||||
|
|
||||||
|
private void OnButtonSelected(bool _) => button.Text.color = data.SelectedColor;
|
||||||
|
private void OnButtonDeselected(bool _) => button.Text.color = data.DeselectedColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f2079225d6e34001ae85f74a0a418d68
|
||||||
|
timeCreated: 1683919878
|
||||||
21
NEG/UI/UnityUi/Buttons/Behaviours/SimpleSoundBehaviour.cs
Normal file
21
NEG/UI/UnityUi/Buttons/Behaviours/SimpleSoundBehaviour.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#if FMOD
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Behaviours
|
||||||
|
{
|
||||||
|
public class SimpleSoundBehaviour : ButtonElementBehaviour
|
||||||
|
{
|
||||||
|
public SimpleSoundBehaviour(BaseButton baseButton, FmodSoundData data) : base(baseButton, data)
|
||||||
|
{
|
||||||
|
//TODO: use silnet to not play sound
|
||||||
|
}
|
||||||
|
|
||||||
|
[FactoryRegistration]
|
||||||
|
private static void RegisterInFactory() =>
|
||||||
|
MonoUiManager.Instance.BehavioursFactory.Register("SimpleSound", typeof(SimpleSoundBehaviour));
|
||||||
|
|
||||||
|
public override void ChangeData(SettingData newData) => throw new System.NotImplementedException();
|
||||||
|
|
||||||
|
public override void Dispose() => throw new System.NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d75c0d86eeab47a1a6340f0b03b83de0
|
||||||
|
timeCreated: 1684002680
|
||||||
@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
|
||||||
{
|
|
||||||
[RequireComponent(typeof(BaseButton))]
|
|
||||||
public abstract class ButtonReaction : MonoBehaviour
|
|
||||||
{
|
|
||||||
private void Awake() => GetComponent<BaseButton>().OnButtonPressed += OnClicked;
|
|
||||||
|
|
||||||
private void OnDestroy() => GetComponent<BaseButton>().OnButtonPressed -= OnClicked;
|
|
||||||
|
|
||||||
protected abstract void OnClicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
using FMODUnity;
|
|
||||||
using System;
|
|
||||||
using TMPro;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.UI;
|
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
|
||||||
{
|
|
||||||
public class ButtonSerializeFields : MonoBehaviour
|
|
||||||
{
|
|
||||||
[field: SerializeField]
|
|
||||||
public Button Button { get; private set; }
|
|
||||||
[field: SerializeField]
|
|
||||||
public TMP_Text Text { get; private set; }
|
|
||||||
[field: SerializeField]
|
|
||||||
public Color SelectedTextColor { get; private set; }
|
|
||||||
[field: SerializeField]
|
|
||||||
public Color DeselectedTextColor { get; private set; }
|
|
||||||
[field: SerializeField]
|
|
||||||
public EventReference HoverEventRef { get; private set; }
|
|
||||||
[field: SerializeField]
|
|
||||||
public EventReference ClickEventRef { get; private set; }
|
|
||||||
|
|
||||||
private void OnValidate()
|
|
||||||
{
|
|
||||||
if(Button == null)
|
|
||||||
Button = GetComponent<Button>();
|
|
||||||
if (Text == null)
|
|
||||||
Text = GetComponentInChildren<TMP_Text>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3f8c6cf4cf18463c86ec1165c61c79b2
|
|
||||||
timeCreated: 1670777232
|
|
||||||
64
NEG/UI/UnityUi/Buttons/CustomNavigationButton.cs
Normal file
64
NEG/UI/UnityUi/Buttons/CustomNavigationButton.cs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons
|
||||||
|
{
|
||||||
|
public class CustomNavigationButton : Button
|
||||||
|
{
|
||||||
|
[SerializeField] [HideInInspector] private OverridableNavigation upOverride;
|
||||||
|
[SerializeField] private OverridableNavigation downOverride;
|
||||||
|
[SerializeField] private OverridableNavigation leftOverride;
|
||||||
|
[SerializeField] private OverridableNavigation rightOverride;
|
||||||
|
|
||||||
|
|
||||||
|
public override void OnMove(AxisEventData eventData)
|
||||||
|
{
|
||||||
|
switch (eventData.moveDir)
|
||||||
|
{
|
||||||
|
case MoveDirection.Left:
|
||||||
|
if (TryNavigate(eventData, leftOverride))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case MoveDirection.Up:
|
||||||
|
if (TryNavigate(eventData, upOverride))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case MoveDirection.Right:
|
||||||
|
if (TryNavigate(eventData, rightOverride))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case MoveDirection.Down:
|
||||||
|
if (TryNavigate(eventData, downOverride))
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
case MoveDirection.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
base.OnMove(eventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryNavigate(BaseEventData eventData, OverridableNavigation overrideNavigation)
|
||||||
|
{
|
||||||
|
if (!overrideNavigation.Override)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (overrideNavigation.Selectable == null || !overrideNavigation.Selectable.IsActive())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
eventData.selectedObject = overrideNavigation.Selectable.gameObject;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class OverridableNavigation
|
||||||
|
{
|
||||||
|
[field: SerializeField] public bool Override { get; private set; }
|
||||||
|
[field: SerializeField] public Selectable Selectable { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/CustomNavigationButton.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/CustomNavigationButton.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d9b5ca8863c240f792232d6e276d8d56
|
||||||
|
timeCreated: 1684520970
|
||||||
3
NEG/UI/UnityUi/Buttons/Reactions.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Reactions.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ccaf0d2f63be41f6956471dcd9c210d9
|
||||||
|
timeCreated: 1709465582
|
||||||
19
NEG/UI/UnityUi/Buttons/Reactions/ButtonReaction.cs
Normal file
19
NEG/UI/UnityUi/Buttons/Reactions/ButtonReaction.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using KBCore.Refs;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons
|
||||||
|
{
|
||||||
|
[RequireComponent(typeof(BaseButton))]
|
||||||
|
public abstract class ButtonReaction : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] [Self(Flag.Optional)] protected BaseButton button;
|
||||||
|
|
||||||
|
protected virtual void Awake() => button.OnButtonPressed += OnClicked;
|
||||||
|
|
||||||
|
protected virtual void OnDestroy() => button.OnButtonPressed -= OnClicked;
|
||||||
|
|
||||||
|
private void OnValidate() => this.ValidateRefs();
|
||||||
|
|
||||||
|
protected abstract void OnClicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,16 +1,13 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
{
|
{
|
||||||
[RequireComponent(typeof(BaseButton))]
|
[RequireComponent(typeof(BaseButton))]
|
||||||
public class ChangeSceneButton : ButtonReaction
|
public class ChangeScene : ButtonReaction
|
||||||
{
|
{
|
||||||
[Header("Leave empty to use int value")]
|
[Header("Leave empty to use int value")] [SerializeField]
|
||||||
[SerializeField] private string sceneName;
|
private string sceneName;
|
||||||
|
|
||||||
[SerializeField] private int sceneIndex;
|
[SerializeField] private int sceneIndex;
|
||||||
|
|
||||||
@ -1,6 +1,4 @@
|
|||||||
using UnityEngine;
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
|
||||||
{
|
{
|
||||||
public class CloseAllWindows : ButtonReaction
|
public class CloseAllWindows : ButtonReaction
|
||||||
{
|
{
|
||||||
@ -1,22 +1,21 @@
|
|||||||
using NEG.UI.UnityUi.Window;
|
using NEG.UI.UnityUi.Window;
|
||||||
using NEG.UI.Window;
|
using NEG.UI.Window;
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
{
|
{
|
||||||
[RequireComponent(typeof(BaseButton))]
|
[RequireComponent(typeof(BaseButton))]
|
||||||
public class CloseWindow : ButtonReaction
|
public class CloseWindow : ButtonReaction
|
||||||
{
|
{
|
||||||
[SerializeField] private MonoWindow windowToClose;
|
[SerializeField] private MonoWindow windowToClose;
|
||||||
|
|
||||||
protected override void OnClicked() => windowToClose.Close();
|
|
||||||
|
|
||||||
private void OnValidate()
|
private void OnValidate()
|
||||||
{
|
{
|
||||||
if (windowToClose != null)
|
if (windowToClose != null)
|
||||||
return;
|
return;
|
||||||
windowToClose = GetComponentInParent<MonoWindow>();
|
windowToClose = GetComponentInParent<MonoWindow>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnClicked() => windowToClose.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
16
NEG/UI/UnityUi/Buttons/Reactions/ExitGame.cs
Normal file
16
NEG/UI/UnityUi/Buttons/Reactions/ExitGame.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
|
{
|
||||||
|
public class ExitGame : ButtonReaction
|
||||||
|
{
|
||||||
|
protected override void OnClicked()
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
EditorApplication.isPlaying = false;
|
||||||
|
#endif
|
||||||
|
Application.Quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Reactions/ExitGame.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Reactions/ExitGame.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 185f765a5bf7487ab85a7d95fc0ef2c7
|
||||||
|
timeCreated: 1709473462
|
||||||
13
NEG/UI/UnityUi/Buttons/Reactions/OpenAsCurrentMainChild.cs
Normal file
13
NEG/UI/UnityUi/Buttons/Reactions/OpenAsCurrentMainChild.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using NEG.UI.UnityUi.Window;
|
||||||
|
using NEG.UI.Window;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
|
{
|
||||||
|
public class OpenAsCurrentMainChild : ButtonReaction
|
||||||
|
{
|
||||||
|
[SerializeField] private MonoWindow windowToOpen;
|
||||||
|
|
||||||
|
protected override void OnClicked() => UiManager.Instance.CurrentMainWindow.OpenAsChild(windowToOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 049e222140c94fc28fb36bca4aaddba4
|
||||||
|
timeCreated: 1686595194
|
||||||
@ -1,18 +1,17 @@
|
|||||||
using NEG.UI.UnityUi.Window;
|
using NEG.UI.UnityUi.Window;
|
||||||
using NEG.UI.UnityUi.WindowSlot;
|
using NEG.UI.UnityUi.WindowSlot;
|
||||||
using System;
|
|
||||||
using UnityEngine;
|
|
||||||
using NEG.UI.Window;
|
using NEG.UI.Window;
|
||||||
using NEG.UI.WindowSlot;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi.Buttons
|
namespace NEG.UI.UnityUi.Buttons.Reactions
|
||||||
{
|
{
|
||||||
[RequireComponent(typeof(BaseButton))]
|
[RequireComponent(typeof(BaseButton))]
|
||||||
public class OpenWindow : ButtonReaction
|
public class OpenWindow : ButtonReaction
|
||||||
{
|
{
|
||||||
[SerializeField] private MonoWindow window;
|
[SerializeField] private MonoWindow window;
|
||||||
[Header("Open on default area slot if empty")]
|
|
||||||
[SerializeField] private MonoWindowSlot slot;
|
[Header("Open on default area slot if empty")] [SerializeField]
|
||||||
|
private MonoWindowSlot slot;
|
||||||
|
|
||||||
protected override void OnClicked() => window.Open(slot);
|
protected override void OnClicked() => window.Open(slot);
|
||||||
}
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d25aba738e174616bcab9bf2d52a3ed1
|
||||||
|
timeCreated: 1683398272
|
||||||
23
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs
Normal file
23
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public class ButtonSettings : MonoBehaviour
|
||||||
|
{
|
||||||
|
[SerializeField] private List<SettingData> settingDatas = new();
|
||||||
|
|
||||||
|
public void Apply(BaseButton button)
|
||||||
|
{
|
||||||
|
foreach (var setting in settingDatas) setting.Apply(button);
|
||||||
|
}
|
||||||
|
|
||||||
|
[ContextMenu("Refresh")]
|
||||||
|
public void Refresh()
|
||||||
|
{
|
||||||
|
settingDatas.Clear();
|
||||||
|
var components = GetComponents<SettingData>();
|
||||||
|
foreach (var data in components) settingDatas.Add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b5292008faae496ab9028ad1faa0a3ba
|
||||||
|
timeCreated: 1683398713
|
||||||
10
NEG/UI/UnityUi/Buttons/Settings/ColorData.cs
Normal file
10
NEG/UI/UnityUi/Buttons/Settings/ColorData.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public class ColorData : SettingData
|
||||||
|
{
|
||||||
|
[field: SerializeField] public Color SelectedColor { get; private set; } = Color.black;
|
||||||
|
[field: SerializeField] public Color DeselectedColor { get; private set; } = Color.black;
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/ColorData.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/ColorData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cec5286cd31b4819981e244b1adb977e
|
||||||
|
timeCreated: 1684001181
|
||||||
14
NEG/UI/UnityUi/Buttons/Settings/FmodSoundData.cs
Normal file
14
NEG/UI/UnityUi/Buttons/Settings/FmodSoundData.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#if FMOD
|
||||||
|
using FMODUnity;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public class FmodSoundData : SettingData
|
||||||
|
{
|
||||||
|
[field: SerializeField] public EventReference SelectedSound { get; private set; }
|
||||||
|
[field: SerializeField] public EventReference ClickedSound { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/FmodSoundData.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/FmodSoundData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8e6a7b10c07d40408ee9492c931e3ec9
|
||||||
|
timeCreated: 1684001979
|
||||||
7
NEG/UI/UnityUi/Buttons/Settings/RemoveFeature.cs
Normal file
7
NEG/UI/UnityUi/Buttons/Settings/RemoveFeature.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public class RemoveFeature : SettingData
|
||||||
|
{
|
||||||
|
public override void Apply(BaseButton button) => button.RemoveSetting(Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/RemoveFeature.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/RemoveFeature.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3b44cdc2e0164ebdb8f6da348d653e77
|
||||||
|
timeCreated: 1684001264
|
||||||
26
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs
Normal file
26
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using KBCore.Refs;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public abstract class SettingData : MonoBehaviour
|
||||||
|
{
|
||||||
|
[field: SerializeField] public string Key { get; private set; }
|
||||||
|
[SerializeField] [Self(Flag.Optional)] private BaseButton attachedButton;
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if (attachedButton != null)
|
||||||
|
Apply(attachedButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
this.ValidateRefs();
|
||||||
|
if (attachedButton == null && TryGetComponent(out ButtonSettings settings))
|
||||||
|
settings.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Apply(BaseButton button) => button.AddOrOverrideSetting(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 49b3fccda2b4485193eada1b3611ea40
|
||||||
|
timeCreated: 1684001079
|
||||||
10
NEG/UI/UnityUi/Buttons/Settings/SpriteData.cs
Normal file
10
NEG/UI/UnityUi/Buttons/Settings/SpriteData.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Settings
|
||||||
|
{
|
||||||
|
public class SpriteData : SettingData
|
||||||
|
{
|
||||||
|
[field: SerializeField] public Sprite SelectedSprite { get; private set; }
|
||||||
|
[field: SerializeField] public Sprite DeselectedSprite { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/Buttons/Settings/SpriteData.cs.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Settings/SpriteData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: aeba07ffa68b4674bc7025ba4f328562
|
||||||
|
timeCreated: 1684001906
|
||||||
@ -5,12 +5,17 @@ using System.Collections.Generic;
|
|||||||
using TMPro;
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi
|
namespace NEG.UI.UnityUi
|
||||||
{
|
{
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public class CarouselList : MonoBehaviour
|
public class CarouselList : MonoBehaviour
|
||||||
{
|
{
|
||||||
|
[SerializeField] private BaseButton nextButton;
|
||||||
|
[SerializeField] private BaseButton prevButton;
|
||||||
|
[SerializeField] private TMP_Text currentOptionText;
|
||||||
|
|
||||||
|
private List<string> options;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Current option
|
/// Current option
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -21,11 +26,19 @@ namespace NEG.UI.UnityUi
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int CurrentOptionId { get; private set; }
|
public int CurrentOptionId { get; private set; }
|
||||||
|
|
||||||
[SerializeField] private BaseButton nextButton;
|
private void Awake()
|
||||||
[SerializeField] private BaseButton prevButton;
|
{
|
||||||
[SerializeField] private TMP_Text currentOptionText;
|
nextButton.OnButtonPressed += SelectNextOption;
|
||||||
|
prevButton.OnButtonPressed += SelectPrevOption;
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> options;
|
private void OnDestroy()
|
||||||
|
{
|
||||||
|
nextButton.OnButtonPressed -= SelectNextOption;
|
||||||
|
prevButton.OnButtonPressed -= SelectPrevOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action<int> OnSelectedItemChanged;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets new options list, automatically first will be selected.
|
/// Sets new options list, automatically first will be selected.
|
||||||
@ -51,9 +64,11 @@ namespace NEG.UI.UnityUi
|
|||||||
Debug.LogError("Invalid option number");
|
Debug.LogError("Invalid option number");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrentOptionId = option;
|
CurrentOptionId = option;
|
||||||
CurrentOption = options[option];
|
CurrentOption = options[option];
|
||||||
currentOptionText.text = CurrentOption;
|
currentOptionText.text = CurrentOption;
|
||||||
|
OnSelectedItemChanged?.Invoke(CurrentOptionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -78,18 +93,7 @@ namespace NEG.UI.UnityUi
|
|||||||
SelectOption(index);
|
SelectOption(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Awake()
|
private void ChangeOption(bool next) =>
|
||||||
{
|
SelectOption((CurrentOptionId + (next ? 1 : -1) + options.Count) % options.Count);
|
||||||
nextButton.OnButtonPressed += SelectNextOption;
|
|
||||||
prevButton.OnButtonPressed += SelectPrevOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void OnDestroy()
|
|
||||||
{
|
|
||||||
nextButton.OnButtonPressed -= SelectNextOption;
|
|
||||||
prevButton.OnButtonPressed -= SelectPrevOption;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ChangeOption(bool next) => SelectOption((CurrentOptionId + (next ? 1 : -1) + options.Count) % options.Count);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 849242dbc213969488426f85222a43a9
|
guid: caeb30c40f1a46041b0ad218cb94902d
|
||||||
folderAsset: yes
|
folderAsset: yes
|
||||||
DefaultImporter:
|
DefaultImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
39
NEG/UI/UnityUi/Editor/ButtonsExtensions.cs
Normal file
39
NEG/UI/UnityUi/Editor/ButtonsExtensions.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Editor
|
||||||
|
{
|
||||||
|
public static class ButtonsExtensions
|
||||||
|
{
|
||||||
|
[MenuItem("CONTEXT/Button/Change To Navigation Button")]
|
||||||
|
public static void ChangeScript(MenuCommand command)
|
||||||
|
{
|
||||||
|
if (command.context == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var button = command.context as Button;
|
||||||
|
var go = new GameObject();
|
||||||
|
var sourceScriptAsset = MonoScript.FromMonoBehaviour(go.AddComponent<CustomNavigationButton>());
|
||||||
|
string relativePath = AssetDatabase.GetAssetPath(sourceScriptAsset);
|
||||||
|
Object.DestroyImmediate(go);
|
||||||
|
|
||||||
|
var chosenTextAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(relativePath);
|
||||||
|
|
||||||
|
if (chosenTextAsset == null)
|
||||||
|
{
|
||||||
|
Debug.LogWarning($"Selected script couldn't be loaded ({relativePath})");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Undo.RegisterCompleteObjectUndo(command.context, "Changing component script");
|
||||||
|
|
||||||
|
var so = new SerializedObject(button);
|
||||||
|
var scriptProperty = so.FindProperty("m_Script");
|
||||||
|
so.Update();
|
||||||
|
scriptProperty.objectReferenceValue = chosenTextAsset;
|
||||||
|
so.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
NEG/UI/UnityUi/Editor/ButtonsExtensions.cs.meta
Normal file
11
NEG/UI/UnityUi/Editor/ButtonsExtensions.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 4b09e744f7ec6704c95ec273584a964f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
36
NEG/UI/UnityUi/Editor/CustomNavigationButtonEditor.cs
Normal file
36
NEG/UI/UnityUi/Editor/CustomNavigationButtonEditor.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.UI;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Editor
|
||||||
|
{
|
||||||
|
[CustomEditor(typeof(CustomNavigationButton), true)]
|
||||||
|
public class CustomNavigationButtonEditor : ButtonEditor
|
||||||
|
{
|
||||||
|
private SerializedProperty downOverrideProperty;
|
||||||
|
private SerializedProperty leftOverrideProperty;
|
||||||
|
private SerializedProperty rightOverrideProperty;
|
||||||
|
private SerializedProperty upOverrideProperty;
|
||||||
|
|
||||||
|
protected override void OnEnable()
|
||||||
|
{
|
||||||
|
base.OnEnable();
|
||||||
|
upOverrideProperty = serializedObject.FindProperty("upOverride");
|
||||||
|
downOverrideProperty = serializedObject.FindProperty("downOverride");
|
||||||
|
leftOverrideProperty = serializedObject.FindProperty("leftOverride");
|
||||||
|
rightOverrideProperty = serializedObject.FindProperty("rightOverride");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
base.OnInspectorGUI();
|
||||||
|
EditorGUILayout.Space();
|
||||||
|
serializedObject.Update();
|
||||||
|
EditorGUILayout.PropertyField(upOverrideProperty);
|
||||||
|
EditorGUILayout.PropertyField(downOverrideProperty);
|
||||||
|
EditorGUILayout.PropertyField(leftOverrideProperty);
|
||||||
|
EditorGUILayout.PropertyField(rightOverrideProperty);
|
||||||
|
serializedObject.ApplyModifiedProperties();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 162f4693585f414b85f0a4210a10a585
|
||||||
|
timeCreated: 1684521873
|
||||||
21
NEG/UI/UnityUi/Editor/NEG.UI.UnityUi.Editor.asmdef
Normal file
21
NEG/UI/UnityUi/Editor/NEG.UI.UnityUi.Editor.asmdef
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"name": "NEG.UI.UnityUi.Editor",
|
||||||
|
"rootNamespace": "",
|
||||||
|
"references": [
|
||||||
|
"GUID:e2aaf8effe1c9634d87b2edda6988a6a",
|
||||||
|
"GUID:5928dc8d9173fd348aa77d4593ca3fd8"
|
||||||
|
],
|
||||||
|
"includePlatforms": [
|
||||||
|
"Editor"
|
||||||
|
],
|
||||||
|
"excludePlatforms": [],
|
||||||
|
"allowUnsafeCode": false,
|
||||||
|
"overrideReferences": false,
|
||||||
|
"precompiledReferences": [
|
||||||
|
""
|
||||||
|
],
|
||||||
|
"autoReferenced": true,
|
||||||
|
"defineConstraints": [],
|
||||||
|
"versionDefines": [],
|
||||||
|
"noEngineReferences": false
|
||||||
|
}
|
||||||
7
NEG/UI/UnityUi/Editor/NEG.UI.UnityUi.Editor.asmdef.meta
Normal file
7
NEG/UI/UnityUi/Editor/NEG.UI.UnityUi.Editor.asmdef.meta
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f8cf2e6d12f27fb47a577cb5a7537ccf
|
||||||
|
AssemblyDefinitionImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
106
NEG/UI/UnityUi/Editor/OverridableNavigationDrawer.cs
Normal file
106
NEG/UI/UnityUi/Editor/OverridableNavigationDrawer.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons;
|
||||||
|
using NEG.Utils.Serialization;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEditor.UIElements;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using UnityEngine.UIElements;
|
||||||
|
using ObjectField = UnityEditor.Search.ObjectField;
|
||||||
|
using Toggle = UnityEngine.UIElements.Toggle;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Editor
|
||||||
|
{
|
||||||
|
[CustomPropertyDrawer(typeof(OverridableNavigation))]
|
||||||
|
public class OverridableNavigationDrawer : PropertyDrawer
|
||||||
|
{
|
||||||
|
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||||
|
{
|
||||||
|
EditorGUI.BeginProperty(position, label, property);
|
||||||
|
|
||||||
|
// Draw label
|
||||||
|
position = EditorGUI.PrefixLabel(position, GUIUtility.GetControlID(FocusType.Passive), label);
|
||||||
|
|
||||||
|
// Don't make child fields be indented
|
||||||
|
int indent = EditorGUI.indentLevel;
|
||||||
|
EditorGUI.indentLevel = 0;
|
||||||
|
|
||||||
|
// Calculate rects
|
||||||
|
var amountRect = new Rect(position.x, position.y, 200, position.height);
|
||||||
|
var unitRect = new Rect(position.x + 35, position.y, 200, position.height);
|
||||||
|
|
||||||
|
// Draw fields - pass GUIContent.none to each so they are drawn without labels
|
||||||
|
EditorGUI.PropertyField(amountRect,
|
||||||
|
property.FindAutoPropertyRelative(nameof(OverridableNavigation.Override)), GUIContent.none);
|
||||||
|
EditorGUI.PropertyField(unitRect,
|
||||||
|
property.FindAutoPropertyRelative(nameof(OverridableNavigation.Selectable)), GUIContent.none);
|
||||||
|
|
||||||
|
// Set indent back to what it was
|
||||||
|
EditorGUI.indentLevel = indent;
|
||||||
|
|
||||||
|
EditorGUI.EndProperty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override VisualElement CreatePropertyGUI(SerializedProperty property)
|
||||||
|
{
|
||||||
|
var container = new VisualElement
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
paddingLeft = 3,
|
||||||
|
paddingRight = -2,
|
||||||
|
flexDirection = FlexDirection.Row,
|
||||||
|
justifyContent = Justify.SpaceBetween
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
string name = property.name;
|
||||||
|
if (name.Length > 0) name = $"{char.ToUpper(name[0])}{name[1..]}";
|
||||||
|
|
||||||
|
var innerContainer = new VisualElement
|
||||||
|
{
|
||||||
|
style =
|
||||||
|
{
|
||||||
|
flexDirection = FlexDirection.Row,
|
||||||
|
justifyContent = Justify.SpaceBetween,
|
||||||
|
marginRight = 2,
|
||||||
|
flexGrow = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var label = new Label(name);
|
||||||
|
|
||||||
|
var enabler = new Toggle();
|
||||||
|
enabler.BindProperty(property.FindPropertyRelative("<Override>k__BackingField"));
|
||||||
|
|
||||||
|
var field = new ObjectField { style = { flexGrow = 100 } };
|
||||||
|
|
||||||
|
var selectableField = property.FindAutoPropertyRelative(nameof(OverridableNavigation.Selectable));
|
||||||
|
|
||||||
|
field.BindProperty(selectableField);
|
||||||
|
field.objectType = typeof(Selectable);
|
||||||
|
|
||||||
|
innerContainer.Add(label);
|
||||||
|
innerContainer.Add(enabler);
|
||||||
|
|
||||||
|
container.Add(innerContainer);
|
||||||
|
container.Add(field);
|
||||||
|
|
||||||
|
container.RegisterCallback<GeometryChangedEvent>(_ =>
|
||||||
|
{
|
||||||
|
var panel = container.panel;
|
||||||
|
var size = panel.visualTree.contentRect.size;
|
||||||
|
|
||||||
|
// magic value measured with ruler, may change in the future!
|
||||||
|
field.style.maxWidth = size.x * 0.55f + 15;
|
||||||
|
});
|
||||||
|
|
||||||
|
field.SetEnabled(enabler.value);
|
||||||
|
enabler.RegisterValueChangedCallback(v =>
|
||||||
|
{
|
||||||
|
field.SetEnabled(v.newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 63ba4de7f1a04763bf035b4a88317a7d
|
||||||
|
timeCreated: 1685212390
|
||||||
30
NEG/UI/UnityUi/MonoController.cs
Normal file
30
NEG/UI/UnityUi/MonoController.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using KBCore.Refs;
|
||||||
|
using NEG.UI.UnityUi.Window;
|
||||||
|
using NegUtils.NEG.UI;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi
|
||||||
|
{
|
||||||
|
public abstract class MonoController : MonoBehaviour, IController
|
||||||
|
{
|
||||||
|
[SerializeField] [Self] protected InterfaceRef<IControllable> controllable;
|
||||||
|
|
||||||
|
protected MonoWindow ControllableAsWindow => (MonoWindow)controllable.Value;
|
||||||
|
|
||||||
|
protected virtual void Awake()
|
||||||
|
{
|
||||||
|
controllable.Value.OnOpened += OnOpened;
|
||||||
|
controllable.Value.OnClosed += OnClosed;
|
||||||
|
controllable.Value.OnBackUsed += OnBackUsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnValidate() => this.ValidateRefs();
|
||||||
|
public IControllable Controllable => controllable.Value;
|
||||||
|
|
||||||
|
protected virtual void OnOpened(object data) { }
|
||||||
|
|
||||||
|
protected virtual void OnClosed() { }
|
||||||
|
|
||||||
|
protected virtual void OnBackUsed(IControllable.BackUsed obj) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
115
NEG/UI/UnityUi/MonoUiInputManger.cs
Normal file
115
NEG/UI/UnityUi/MonoUiInputManger.cs
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
using NEG.UI.UnityUi.Window;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
using UnityEngine.InputSystem;
|
||||||
|
using UnityEngine.InputSystem.UI;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi
|
||||||
|
{
|
||||||
|
public enum SelectionSource
|
||||||
|
{
|
||||||
|
Pointer,
|
||||||
|
Direction
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UiInputModule
|
||||||
|
{
|
||||||
|
public SelectionSource CurrentSelectionSource { get; protected set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DefaultInputModule : UiInputModule
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
SetDirectionInput();
|
||||||
|
else
|
||||||
|
SetPointerInput();
|
||||||
|
|
||||||
|
//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 mouseAction = new InputAction(binding: "/<Mouse>/*");
|
||||||
|
mouseAction.performed += context =>
|
||||||
|
{
|
||||||
|
if (CurrentSelectionSource == SelectionSource.Pointer)
|
||||||
|
return;
|
||||||
|
SetPointerInput();
|
||||||
|
};
|
||||||
|
mouseAction.Enable();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSelectionChangeStarted()
|
||||||
|
{
|
||||||
|
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()
|
||||||
|
{
|
||||||
|
CurrentSelectionSource = SelectionSource.Pointer;
|
||||||
|
Cursor.visible = true;
|
||||||
|
|
||||||
|
if (EventSystem.current == null)
|
||||||
|
{
|
||||||
|
SetDirectionInput();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var data = new PointerEventData(EventSystem.current);
|
||||||
|
for (var current = result.gameObject.transform;
|
||||||
|
current != null;
|
||||||
|
current = current.parent)
|
||||||
|
ExecuteEvents.Execute(current.gameObject, data, ExecuteEvents.pointerEnterHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/MonoUiInputManger.cs.meta
Normal file
3
NEG/UI/UnityUi/MonoUiInputManger.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f6cd55755dda4f71a4257fac75cb902d
|
||||||
|
timeCreated: 1684009354
|
||||||
@ -1,43 +1,93 @@
|
|||||||
using NEG.UI.Area;
|
using NEG.UI.Area;
|
||||||
using NEG.UI.Popup;
|
using NEG.UI.Popup;
|
||||||
|
using NEG.UI.UnityUi.Buttons.Behaviours;
|
||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
using NEG.UI.UnityUi.Popup;
|
using NEG.UI.UnityUi.Popup;
|
||||||
using System.Collections.Generic;
|
using NEG.UI.UnityUi.Window;
|
||||||
|
using NEG.Utils;
|
||||||
|
using System;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.AddressableAssets;
|
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
using Object = UnityEngine.Object;
|
||||||
|
|
||||||
namespace NEG.UI.UnityUi
|
namespace NEG.UI.UnityUi
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implements ui using UnityUI and Unity Event System with New Input System.
|
/// Implements ui using UnityUI and Unity Event System with New Input System.
|
||||||
/// <para>You have to provide prefabs with addresses:</para>
|
/// <para>You have to provide prefabs within resources:</para>
|
||||||
/// <para> - NEG/UI/PopupCanvas - prefab with canvas to create popups (will be created on every scene)</para>
|
/// <para> - UI/PopupCanvas - prefab with canvas to create popups (will be created on every scene)</para>
|
||||||
/// <para> - NEG/UI/DefaultPopupPrefab - prefab of default popup with 2 options (has to have <see cref="MonoDefaultPopup"/> component)</para>
|
/// <para>
|
||||||
|
/// - UI/DefaultPopupPrefab - prefab of default popup with 2 options (has to have
|
||||||
|
/// <see cref="MonoDefaultPopup" /> component)
|
||||||
|
/// </para>
|
||||||
|
/// NEG_UI_DISABLE_WARNING_DEFAULT_SELECTION
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MonoUiManager : UiManager
|
public class MonoUiManager : UiManager, IDisposable
|
||||||
{
|
{
|
||||||
//TODO: use default unity selection
|
|
||||||
//TODO: window snaping to slots
|
|
||||||
|
|
||||||
private readonly MonoDefaultPopup defaultPopupPrefab;
|
|
||||||
private readonly GameObject canvasPrefab;
|
private readonly GameObject canvasPrefab;
|
||||||
|
|
||||||
public MonoUiManager(IArea startArea) : base(startArea)
|
//TODO: editor to auto add slots, buttons
|
||||||
|
|
||||||
|
private readonly MonoDefaultPopup defaultPopupPrefab;
|
||||||
|
|
||||||
|
private readonly UiInputModule inputModule;
|
||||||
|
|
||||||
|
public MonoUiManager(IArea startArea, Type inputModuleType, ButtonSettings defaultUiSettings) : base(startArea)
|
||||||
{
|
{
|
||||||
var prefabs =
|
Instance = this;
|
||||||
Addressables.LoadAssetsAsync<GameObject>(new List<string>() { "NEG/UI/PopupCanvas", "NEG/UI/DefaultPopupPrefab" }, (_) => { }, Addressables.MergeMode.Union).WaitForCompletion();
|
|
||||||
|
|
||||||
Assert.AreEqual(prefabs.Count, 2, "No prefabs was provided. Please check MonoUiManager class documentation");
|
var popupCanvas = Resources.Load<GameObject>("UI/PopupCanvas");
|
||||||
Assert.IsNotNull(prefabs[0].GetComponent<Canvas>());
|
var defaultPopup = Resources.Load<GameObject>("UI/DefaultPopupPrefab");
|
||||||
Assert.IsNotNull(prefabs[1].GetComponent<MonoDefaultPopup>());
|
|
||||||
|
|
||||||
canvasPrefab = prefabs[0];
|
Assert.IsNotNull(popupCanvas,
|
||||||
defaultPopupPrefab = prefabs[1].GetComponent<MonoDefaultPopup>();
|
"No canvas prefab was provided. Please check MonoUiManager class documentation");
|
||||||
|
Assert.IsNotNull(defaultPopup,
|
||||||
|
"No popup prefab was provided. Please check MonoUiManager class documentation");
|
||||||
|
Assert.IsNotNull(popupCanvas.GetComponent<Canvas>());
|
||||||
|
Assert.IsNotNull(defaultPopup.GetComponent<MonoDefaultPopup>());
|
||||||
|
|
||||||
|
canvasPrefab = popupCanvas;
|
||||||
|
defaultPopupPrefab = defaultPopup.GetComponent<MonoDefaultPopup>();
|
||||||
|
|
||||||
SpawnDefaultPopup();
|
SpawnDefaultPopup();
|
||||||
|
|
||||||
SceneManager.activeSceneChanged += (_, _) => SpawnDefaultPopup();
|
SceneManager.activeSceneChanged += (_, _) => SpawnDefaultPopup();
|
||||||
|
|
||||||
|
BehavioursFactory = new KeyBasedFactory<string, ButtonElementBehaviour>();
|
||||||
|
BehavioursFactory.FireRegistration();
|
||||||
|
|
||||||
|
inputModule = (UiInputModule)Activator.CreateInstance(inputModuleType);
|
||||||
|
DefaultUiSettings = defaultUiSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: use default unity selection
|
||||||
|
//TODO: window snaping to slots
|
||||||
|
public static new MonoUiManager Instance { get; private set; }
|
||||||
|
|
||||||
|
public ButtonSettings DefaultUiSettings { get; }
|
||||||
|
public KeyBasedFactory<string, ButtonElementBehaviour> BehavioursFactory { get; }
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
base.Dispose();
|
||||||
|
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()
|
private void SpawnDefaultPopup()
|
||||||
@ -47,6 +97,5 @@ namespace NEG.UI.UnityUi
|
|||||||
SetDefaultPopup(Object.Instantiate(defaultPopupPrefab, canvas.transform));
|
SetDefaultPopup(Object.Instantiate(defaultPopupPrefab, canvas.transform));
|
||||||
currentDefaultPopup.Close(true);
|
currentDefaultPopup.Close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5,10 +5,11 @@
|
|||||||
"GUID:343deaaf83e0cee4ca978e7df0b80d21",
|
"GUID:343deaaf83e0cee4ca978e7df0b80d21",
|
||||||
"GUID:7361f1d9c43da6649923760766194746",
|
"GUID:7361f1d9c43da6649923760766194746",
|
||||||
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
"GUID:6055be8ebefd69e48b49212b09b47b2f",
|
||||||
|
"GUID:23eed6c2401dca1419d1ebd180e58c5a",
|
||||||
|
"GUID:33759803a11f4d538227861a78aba30b",
|
||||||
"GUID:0c752da273b17c547ae705acf0f2adf2",
|
"GUID:0c752da273b17c547ae705acf0f2adf2",
|
||||||
"GUID:9e24947de15b9834991c9d8411ea37cf",
|
"GUID:3c4294719a93e3c4e831a9ff0c261e8a",
|
||||||
"GUID:84651a3751eca9349aac36a66bba901b",
|
"GUID:75469ad4d38634e559750d17036d5f7c"
|
||||||
"GUID:23eed6c2401dca1419d1ebd180e58c5a"
|
|
||||||
],
|
],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user