using System; using System.Collections; using System.Collections.Generic; using System.Threading; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UIElements; // ReSharper disable MemberCanBeProtected.Global // ReSharper disable ClassWithVirtualMembersNeverInherited.Global // ReSharper disable UnusedMember.Global namespace BITKit.UX { public class UIToolKitPanel : MonoBehaviour,IUXPanel { [RuntimeInitializeOnLoadMethod] private static void Reload() { inputActionGroup = new InputActionGroup { allowGlobalActivation = false, Source = nameof(UIToolKitPanel) }; inputActionGroup.allowInput.AddElement(0); } public UIToolKitPanel() { Index = GetType().FullName; } [Header(Constant.Header.Components)] [SerializeField] protected UIDocument document; [Header(Constant.Header.Settings)] [SerializeField] private bool isAnimate; [SerializeField] private bool allowCursor; [SerializeField] private bool allowInput; [SerializeField] private bool autoEntry; [Header(Constant.Header.Settings)] [SerializeField] private Optional entryDuration; [SerializeField] private Optional exitDuration; protected static InputActionGroup inputActionGroup = new() { allowGlobalActivation = false, Source = nameof(UIToolKitPanel) }; public bool IsAnimate => isAnimate; public bool IsValid => cancellationToken.IsCancellationRequested is false; public string Index { get; private set; } public bool AllowCursor => allowCursor; public bool AllowInput => allowInput; protected CancellationToken cancellationToken { get; private set; } protected float TargetOpacity { get; private set; } protected virtual VisualElement background => document.rootVisualElement; protected float CurrentOpacity { get => background?.GetOpacity() ?? _currentOpacity; set { _currentOpacity = value; background?.SetOpacity(value); } } private float _currentOpacity; protected virtual void Awake() { cancellationToken = gameObject.GetCancellationTokenOnDestroy(); Index= typeof(UIToolKitPanel) == GetType() ? gameObject.name : GetType().Name; document.rootVisualElement.SetActive(false); background?.SetOpacity(0); } protected virtual void Start() { BITKit.UX.UXUtils.Inject(this); if(IsValid && autoEntry) UXService.Entry(this); } public bool IsEntered { get; set; } public void Entry() { UXService.Entry(this); } protected virtual void OnEnable()=>UXService.Register(this); protected virtual void OnDisable()=>UXService.UnRegister(this); protected virtual void OnPanelEntry(){} protected virtual void OnPanelExit(){} void IEntryElement.Entry() { try { CurrentOpacity = 0; TargetOpacity = 1; document.rootVisualElement.SetActive(true); OnEntry?.Invoke(); } catch (Exception e) { Debug.Log(gameObject.name); throw; } } async UniTask IEntryElement.EntryAsync() { if (entryDuration.Allow is false) return; while (CurrentOpacity < 1 && TargetOpacity is 1) { await UniTask.NextFrame(cancellationToken); } } void IEntryElement.Entered() { //inputActionGroup.allowInput.AddElement(this); OnPanelEntry(); } void IEntryElement.Exit() { if (IsValid is false) return; TargetOpacity = 0; //inputActionGroup.allowInput.RemoveElement(this); OnPanelExit(); } async UniTask IEntryElement.ExitAsync() { if (exitDuration.Allow is false) return; while (CurrentOpacity > 0 && TargetOpacity is 0) { await UniTask.NextFrame(cancellationToken); } OnExit?.Invoke(); } void IEntryElement.Exited() { document.rootVisualElement.SetActive(false); } public event Action OnEntry; public event Action OnExit; public virtual void OnUpdate(float deltaTime) { var duration = 1f; if (TargetOpacity is 1) { if (entryDuration.Allow is false) { CurrentOpacity = TargetOpacity; return; } duration = entryDuration.Value; } else { if (exitDuration.Allow is false) { CurrentOpacity = TargetOpacity; return; } duration = exitDuration.Value; } CurrentOpacity = Mathf.MoveTowards(CurrentOpacity,TargetOpacity,1f/duration * Time.deltaTime); } } }