ui system improved
This commit is contained in:
parent
c0923cc884
commit
7aecbeb240
54
KeyBasedFactory.cs
Normal file
54
KeyBasedFactory.cs
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
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
|
||||||
|
{
|
||||||
|
public FactoryRegistration() { }
|
||||||
|
}
|
||||||
|
}
|
||||||
3
KeyBasedFactory.cs.meta
Normal file
3
KeyBasedFactory.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2e0d3df1ddd34209bfb7262b4e51abfe
|
||||||
|
timeCreated: 1683917310
|
||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "NEG.UI",
|
"name": "NEG.UI",
|
||||||
"rootNamespace": "",
|
"rootNamespace": "",
|
||||||
"references": [],
|
"references": ["GUID:3c4294719a93e3c4e831a9ff0c261e8a"],
|
||||||
"includePlatforms": [],
|
"includePlatforms": [],
|
||||||
"excludePlatforms": [],
|
"excludePlatforms": [],
|
||||||
"allowUnsafeCode": false,
|
"allowUnsafeCode": false,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ 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 NEG.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|||||||
@ -1,72 +1,92 @@
|
|||||||
using FMOD.Studio;
|
using KBCore.Refs;
|
||||||
using FMODUnity;
|
using NEG.UI.UnityUi.Buttons.Reaction;
|
||||||
|
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.Serialization;
|
||||||
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 delegate void SelectionHandler(bool isSilent);
|
||||||
|
/// <summary>
|
||||||
|
/// is silent
|
||||||
|
/// </summary>
|
||||||
|
public event SelectionHandler OnSelected;
|
||||||
|
public event SelectionHandler OnDeselected;
|
||||||
public event Action OnButtonPressed;
|
public event Action OnButtonPressed;
|
||||||
|
|
||||||
public bool Interactable { get => serializeFields.Button.interactable; set => serializeFields.Button.interactable = value; }
|
public bool Interactable { get => button.interactable; set => button.interactable = value; }
|
||||||
|
|
||||||
[SerializeField]
|
public TMP_Text Text => text;
|
||||||
protected ButtonSerializeFields serializeFields;
|
|
||||||
|
|
||||||
private bool isHovered;
|
private bool isHovered;
|
||||||
|
|
||||||
public virtual void OnSelect(BaseEventData eventData)
|
[SerializeField, Self] private Button button;
|
||||||
{
|
[SerializeField, Child(Flag.Optional)] private TMP_Text text;
|
||||||
if (serializeFields.Text)
|
[SerializeField, Child(Flag.Optional)] private Image icon;
|
||||||
serializeFields.Text.color = serializeFields.SelectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnDeselect(BaseEventData eventData)
|
[SerializeField] private ButtonSettings groupButtonSettings;
|
||||||
{
|
//[SerializeField, Self(Flag.Optional)] private ButtonSettingOverride overrideSettings;
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.DeselectedTextColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPointerEnter(PointerEventData eventData)
|
private Dictionary<string, ButtonElementBehaviour> behaviours = new Dictionary<string, ButtonElementBehaviour>();
|
||||||
{
|
|
||||||
isHovered = true;
|
public virtual void OnSelect(BaseEventData eventData) => OnSelected?.Invoke(eventData is SilentEventData);
|
||||||
if (serializeFields.Text)
|
|
||||||
serializeFields.Text.color = serializeFields.SelectedTextColor;
|
public void OnDeselect(BaseEventData eventData) => OnDeselected?.Invoke(eventData is SilentEventData);
|
||||||
}
|
|
||||||
|
public void OnPointerEnter(PointerEventData eventData) => EventSystem.current.SetSelectedGameObject(gameObject);
|
||||||
|
|
||||||
public void OnPointerExit(PointerEventData eventData)
|
public void OnPointerExit(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
isHovered = false;
|
if(EventSystem.current.currentSelectedGameObject == gameObject)
|
||||||
if (serializeFields.Text)
|
EventSystem.current.SetSelectedGameObject(null);
|
||||||
serializeFields.Text.color = serializeFields.DeselectedTextColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetText(string text)
|
public void SetText(string txt)
|
||||||
{
|
{
|
||||||
if(serializeFields == null)
|
if(text == null)
|
||||||
return;
|
return;
|
||||||
if(serializeFields.Text == null)
|
text.text = txt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOrOverrideSetting(SettingData data)
|
||||||
|
{
|
||||||
|
if (behaviours.TryGetValue(data.Key, out var setting))
|
||||||
|
{
|
||||||
|
setting.ChangeData(data);
|
||||||
return;
|
return;
|
||||||
serializeFields.Text.text = text;
|
}
|
||||||
|
behaviours.Add("ChangeTextColor", 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 Awake()
|
protected virtual void Awake()
|
||||||
{
|
{
|
||||||
if(serializeFields == null)
|
button.onClick.AddListener(OnClicked);
|
||||||
serializeFields = GetComponent<ButtonSerializeFields>();
|
groupButtonSettings.Apply(this);
|
||||||
serializeFields.Button.onClick.AddListener(OnClicked);
|
|
||||||
OnDeselect(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnValidate()
|
private void Start() => OnDeselect(null);
|
||||||
{
|
|
||||||
if(serializeFields == null)
|
private void OnValidate() => this.ValidateRefs();
|
||||||
serializeFields = GetComponent<ButtonSerializeFields>();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void OnClicked()
|
protected virtual void OnClicked()
|
||||||
{
|
{
|
||||||
|
|||||||
@ -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:
|
||||||
|
|||||||
@ -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
|
|
||||||
3
NEG/UI/UnityUi/Buttons/Overrides.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Overrides.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c431f6df68cb4163b9764b6a87abd31a
|
||||||
|
timeCreated: 1683915618
|
||||||
3
NEG/UI/UnityUi/Buttons/Reaction.meta
Normal file
3
NEG/UI/UnityUi/Buttons/Reaction.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 953c3353e3af44258625fe607ede632b
|
||||||
|
timeCreated: 1683915598
|
||||||
22
NEG/UI/UnityUi/Buttons/Reaction/ButtonElementBehaviour.cs
Normal file
22
NEG/UI/UnityUi/Buttons/Reaction/ButtonElementBehaviour.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
|
using System;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Reaction
|
||||||
|
{
|
||||||
|
public abstract class ButtonElementBehaviour : IDisposable
|
||||||
|
{
|
||||||
|
protected SettingData baseData;
|
||||||
|
protected readonly BaseButton button;
|
||||||
|
|
||||||
|
public ButtonElementBehaviour(BaseButton baseButton, SettingData settingData)
|
||||||
|
{
|
||||||
|
button = baseButton;
|
||||||
|
baseData = settingData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ChangeData(SettingData newData) => baseData = newData;
|
||||||
|
|
||||||
|
public abstract void Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a5e3decad6424cb288eff3e6f7e0d28e
|
||||||
|
timeCreated: 1683919740
|
||||||
46
NEG/UI/UnityUi/Buttons/Reaction/ChangeTextColorBehaviour.cs
Normal file
46
NEG/UI/UnityUi/Buttons/Reaction/ChangeTextColorBehaviour.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
|
using NEG.Utils;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Reaction
|
||||||
|
{
|
||||||
|
public class ChangeTextColorBehaviour : ButtonElementBehaviour
|
||||||
|
{
|
||||||
|
private ColorData data;
|
||||||
|
|
||||||
|
public ChangeTextColorBehaviour(BaseButton baseButton, ColorData data) : base(baseButton, data)
|
||||||
|
{
|
||||||
|
if (baseButton.Text == null)
|
||||||
|
{
|
||||||
|
Debug.LogError("Button without text was provided");
|
||||||
|
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
|
||||||
24
NEG/UI/UnityUi/Buttons/Reaction/SimpleSoundBehaviour.cs
Normal file
24
NEG/UI/UnityUi/Buttons/Reaction/SimpleSoundBehaviour.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
|
using NEG.Utils;
|
||||||
|
#if FMOD
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi.Buttons.Reaction
|
||||||
|
{
|
||||||
|
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
|
||||||
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
|
||||||
32
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs
Normal file
32
NEG/UI/UnityUi/Buttons/Settings/ButtonSettings.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
|
||||||
|
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
|
||||||
28
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs
Normal file
28
NEG/UI/UnityUi/Buttons/Settings/SettingData.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using KBCore.Refs;
|
||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Serialization;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
public virtual void Apply(BaseButton button) => button.AddOrOverrideSetting(this);
|
||||||
|
|
||||||
|
private void Awake()
|
||||||
|
{
|
||||||
|
if(attachedButton != null)
|
||||||
|
Apply(attachedButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnValidate()
|
||||||
|
{
|
||||||
|
this.ValidateRefs();
|
||||||
|
if (attachedButton == null && TryGetComponent(out ButtonSettings settings))
|
||||||
|
settings.Refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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
|
||||||
82
NEG/UI/UnityUi/MonoUiInputManger.cs
Normal file
82
NEG/UI/UnityUi/MonoUiInputManger.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
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 class DefaultInputModule : UiInputModule
|
||||||
|
{
|
||||||
|
public SelectionSource CurrentSelectionSource { get; private set; }
|
||||||
|
|
||||||
|
public DefaultInputModule()
|
||||||
|
{
|
||||||
|
var defaultActions = new DefaultInputActions();
|
||||||
|
InputActionReference.Create(defaultActions.UI.Navigate).action.performed += (ctx) => OnSelectionChangeStarted();
|
||||||
|
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)
|
||||||
|
return;
|
||||||
|
SetDirectionInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetDirectionInput()
|
||||||
|
{
|
||||||
|
CurrentSelectionSource = SelectionSource.Direction;
|
||||||
|
Cursor.visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPointerInput()
|
||||||
|
{
|
||||||
|
CurrentSelectionSource = SelectionSource.Pointer;
|
||||||
|
Cursor.visible = true;
|
||||||
|
if (EventSystem.current.currentInputModule != null)
|
||||||
|
{
|
||||||
|
var module = (InputSystemUIInputModule)EventSystem.current.currentInputModule;
|
||||||
|
var result = module.GetLastRaycastResult(0);
|
||||||
|
var data = new PointerEventData(EventSystem.current);
|
||||||
|
for (var current = result.gameObject.transform;
|
||||||
|
current != null;
|
||||||
|
current = current.parent)
|
||||||
|
{
|
||||||
|
ExecuteEvents.Execute(current.gameObject, data, ExecuteEvents.pointerEnterHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
//EventSystem.current.SetSelectedGameObject(result.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
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,61 @@
|
|||||||
using NEG.UI.Area;
|
using NEG.UI.Area;
|
||||||
using NEG.UI.Popup;
|
using NEG.UI.Popup;
|
||||||
|
using NEG.UI.UnityUi.Buttons.Reaction;
|
||||||
|
using NEG.UI.UnityUi.Buttons.Settings;
|
||||||
using NEG.UI.UnityUi.Popup;
|
using NEG.UI.UnityUi.Popup;
|
||||||
|
using NEG.Utils;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.AddressableAssets;
|
|
||||||
using UnityEngine.Assertions;
|
using UnityEngine.Assertions;
|
||||||
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>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class MonoUiManager : UiManager
|
public class MonoUiManager : UiManager
|
||||||
{
|
{
|
||||||
//TODO: use default unity selection
|
//TODO: use default unity selection
|
||||||
//TODO: window snaping to slots
|
//TODO: window snaping to slots
|
||||||
|
public static new MonoUiManager Instance { get; private set; }
|
||||||
|
|
||||||
|
public KeyBasedFactory<string, ButtonElementBehaviour> BehavioursFactory { get; private set; }
|
||||||
|
|
||||||
private readonly MonoDefaultPopup defaultPopupPrefab;
|
private readonly MonoDefaultPopup defaultPopupPrefab;
|
||||||
private readonly GameObject canvasPrefab;
|
private readonly GameObject canvasPrefab;
|
||||||
|
|
||||||
public MonoUiManager(IArea startArea) : base(startArea)
|
private UiInputModule inputModule;
|
||||||
|
|
||||||
|
public MonoUiManager(IArea startArea, Type inputModuleType) : 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>());
|
//Addressables.LoadAssetsAsync<GameObject>(new List<string>() { "NEG/UI/PopupCanvas", "NEG/UI/DefaultPopupPrefab" }, (_) => { }, Addressables.MergeMode.Union).WaitForCompletion();
|
||||||
|
|
||||||
canvasPrefab = prefabs[0];
|
Assert.IsNotNull(popupCanvas,"No canvas prefab was provided. Please check MonoUiManager class documentation");
|
||||||
defaultPopupPrefab = prefabs[1].GetComponent<MonoDefaultPopup>();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SpawnDefaultPopup()
|
private void SpawnDefaultPopup()
|
||||||
|
|||||||
@ -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": [],
|
||||||
|
|||||||
11
NEG/UI/UnityUi/SilentEventData.cs
Normal file
11
NEG/UI/UnityUi/SilentEventData.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using UnityEngine.EventSystems;
|
||||||
|
|
||||||
|
namespace NEG.UI.UnityUi
|
||||||
|
{
|
||||||
|
public class SilentEventData : BaseEventData
|
||||||
|
{
|
||||||
|
public SilentEventData(EventSystem eventSystem) : base(eventSystem)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
NEG/UI/UnityUi/SilentEventData.cs.meta
Normal file
3
NEG/UI/UnityUi/SilentEventData.cs.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 718df112d05a4270bad895acce9dfa87
|
||||||
|
timeCreated: 1684008766
|
||||||
@ -21,6 +21,8 @@ namespace NEG.UI.UnityUi.Window
|
|||||||
[SerializeField] private List<MonoWindowSlot> windowSlots;
|
[SerializeField] private List<MonoWindowSlot> windowSlots;
|
||||||
[SerializeField] private WindowController controller;
|
[SerializeField] private WindowController controller;
|
||||||
|
|
||||||
|
[SerializeField] private GameObject defaultSelectedItem;
|
||||||
|
|
||||||
public void SetOpenedState(IWindowSlot parentSlot)
|
public void SetOpenedState(IWindowSlot parentSlot)
|
||||||
{
|
{
|
||||||
gameObject.SetActive(true);
|
gameObject.SetActive(true);
|
||||||
@ -48,6 +50,8 @@ namespace NEG.UI.UnityUi.Window
|
|||||||
{
|
{
|
||||||
if (controller == null)
|
if (controller == null)
|
||||||
controller = GetComponent<WindowController>();
|
controller = GetComponent<WindowController>();
|
||||||
|
if(defaultSelectedItem == null)
|
||||||
|
Debug.LogWarning("Window should have default selected item set");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OpenWindow(IWindow window, object data = null)
|
public void OpenWindow(IWindow window, object data = null)
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace NEG.Utils
|
|||||||
/// <param name="type">Interface type.</param>
|
/// <param name="type">Interface type.</param>
|
||||||
public RequireInterfaceAttribute(System.Type type)
|
public RequireInterfaceAttribute(System.Type type)
|
||||||
{
|
{
|
||||||
this.requiredType = type;
|
requiredType = type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,11 +1,15 @@
|
|||||||
using System;
|
using JetBrains.Annotations;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace NEG.Utils.Timing
|
namespace NEG.Utils.Timing
|
||||||
{
|
{
|
||||||
public class AutoTimeMachine
|
public class AutoTimeMachine
|
||||||
{
|
{
|
||||||
|
[PublicAPI]
|
||||||
public double Interval { get; set; }
|
public double Interval { get; set; }
|
||||||
public Action Action { get; set; }
|
|
||||||
|
[PublicAPI]
|
||||||
|
public Action Action { get; }
|
||||||
|
|
||||||
private readonly TimeMachine machine;
|
private readonly TimeMachine machine;
|
||||||
|
|
||||||
|
|||||||
@ -5,66 +5,61 @@ namespace NEG.Utils.Timing
|
|||||||
{
|
{
|
||||||
public class TimeMachine
|
public class TimeMachine
|
||||||
{
|
{
|
||||||
private double time;
|
private double timeInternal;
|
||||||
|
|
||||||
public TimeMachine()
|
public TimeMachine()
|
||||||
{
|
{
|
||||||
time = 0;
|
timeInternal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds time into the TimeMachine
|
/// Adds time into the TimeMachine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">Amount of time to be added</param>
|
/// <param name="time">Amount of time to be added</param>
|
||||||
public void Accumulate(double time)
|
public void Accumulate(double time) => timeInternal += time;
|
||||||
{
|
|
||||||
this.time += time;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retrieves given amount of time from the TimeMachine
|
/// Retrieves given amount of time from the TimeMachine
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="maxTime"></param>
|
/// <param name="maxTime"></param>
|
||||||
/// <returns>Amount of time retrievend</returns>
|
/// <returns>Amount of time retrieved</returns>
|
||||||
public double Retrieve(double maxTime)
|
public double Retrieve(double maxTime)
|
||||||
{
|
{
|
||||||
if(!double.IsFinite(maxTime))
|
if(!double.IsFinite(maxTime))
|
||||||
{
|
{
|
||||||
double timeRetrieved = time;
|
double timeRetrieved = timeInternal;
|
||||||
time = 0;
|
timeInternal = 0;
|
||||||
return timeRetrieved;
|
return timeRetrieved;
|
||||||
}
|
}
|
||||||
double timeLeft = time - maxTime;
|
double timeLeft = timeInternal - maxTime;
|
||||||
time = Math.Max(timeLeft, 0);
|
timeInternal = Math.Max(timeLeft, 0);
|
||||||
return Math.Min(maxTime + timeLeft, maxTime);
|
return Math.Min(maxTime + timeLeft, maxTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Attempts to retrieves given amount of time from the TimeMachine <br/>
|
/// Attempts to retrieves given amount of time from the TimeMachine <br/>
|
||||||
/// If there is enough <paramref name="time"/> accumulated in this machine subtructs that amount and returns true, otherwise returns false
|
/// If there is enough <paramref name="time"/> accumulated in this machine subtracts that amount and returns true, otherwise returns false
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time"></param>
|
/// <param name="time"></param>
|
||||||
public bool TryRetrieve(double time)
|
public bool TryRetrieve(double time)
|
||||||
{
|
{
|
||||||
if (this.time >= time)
|
if (!(timeInternal >= time))
|
||||||
{
|
|
||||||
this.time -= time;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
|
timeInternal -= time;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Result is equivalent to calling <see cref="TryRetrieve(double)"/> as many times as possible, but is faster for larger <paramref name="limit"/> values
|
/// Result is equivalent to calling <see cref="TryRetrieve(double)"/> as many times as possible, but is faster for larger <paramref name="limit"/> values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="interval">Single unit of warp time, must be positive/param>
|
/// <param name="interval">Single unit of warp time, must be positive</param>
|
||||||
/// <param name="limit">Maximum amount of warps, must be positive</param>
|
/// <param name="limit">Maximum amount of warps, must be positive</param>
|
||||||
/// <returns>Amount of warps</returns>
|
/// <returns>Amount of warps</returns>
|
||||||
public int RetrieveAll(double interval, int limit = int.MaxValue)
|
public int RetrieveAll(double interval, int limit = int.MaxValue)
|
||||||
{
|
{
|
||||||
int result = Mathf.FloorToInt((float)(time / interval));
|
int result = Mathf.FloorToInt((float)(timeInternal / interval));
|
||||||
result = Math.Clamp(result, 0, limit);
|
result = Math.Clamp(result, 0, limit);
|
||||||
time -= result * interval;
|
timeInternal -= result * interval;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user