StationObscurum/Assets/Packages/Heat - Complete Modern UI/Scripts/UI Elements/ShopButtonManager.cs
2024-02-01 22:45:59 -05:00

405 lines
15 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using TMPro;
namespace Michsky.UI.Heat
{
[ExecuteInEditMode]
[DisallowMultipleComponent]
[RequireComponent(typeof(Animator))]
public class ShopButtonManager : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, ISelectHandler, IDeselectHandler, ISubmitHandler
{
// Content
public State state = State.Default;
public Sprite buttonIcon;
public string buttonTitle = "Button";
public string titleLocalizationKey;
public string buttonDescription = "Description";
public string descriptionLocalizationKey;
public Sprite priceIcon;
public string priceText = "123";
public BackgroundFilter backgroundFilter;
// Resources
[SerializeField] private Animator animator;
public ButtonManager purchaseButton;
public ButtonManager purchasedButton;
public GameObject purchasedIndicator;
public ModalWindowManager purchaseModal;
public Image iconObj;
public Image priceIconObj;
public TextMeshProUGUI titleObj;
public TextMeshProUGUI descriptionObj;
public TextMeshProUGUI priceObj;
public Image filterObj;
public List<Sprite> filters = new List<Sprite>();
// Settings
public bool isInteractable = true;
public bool enableIcon = false;
public bool enableTitle = true;
public bool enableDescription = true;
public bool enablePrice = true;
public bool enableFilter = true;
public bool useModalWindow = true;
public bool useCustomContent = false;
public bool useLocalization = true;
public bool bypassUpdateOnEnable = false;
public bool useUINavigation = false;
public Navigation.Mode navigationMode = Navigation.Mode.Automatic;
public GameObject selectOnUp;
public GameObject selectOnDown;
public GameObject selectOnLeft;
public GameObject selectOnRight;
public bool wrapAround = false;
public bool useSounds = true;
// Events
public UnityEvent onPurchaseClick = new UnityEvent();
public UnityEvent onPurchase = new UnityEvent();
public UnityEvent onClick = new UnityEvent();
public UnityEvent onHover = new UnityEvent();
public UnityEvent onLeave = new UnityEvent();
public UnityEvent onSelect = new UnityEvent();
public UnityEvent onDeselect = new UnityEvent();
// Helpers
bool isInitialized = false;
float cachedStateLength = 0.5f;
Button targetButton;
#if UNITY_EDITOR
public int latestTabIndex = 0;
#endif
public enum State { Default, Purchased }
public enum BackgroundFilter
{
Aqua,
Dawn,
Dusk,
Emerald,
Kylo,
Memory,
Mice,
Pinky,
Retro,
Rock,
Sunset,
Violet,
Warm,
Random
}
void Awake()
{
cachedStateLength = HeatUIInternalTools.GetAnimatorClipLength(animator, "ShopButton_Highlighted") + 0.1f;
InitializePurchaseEvents();
}
void OnEnable()
{
if (!isInitialized) { Initialize(); }
if (!bypassUpdateOnEnable) { UpdateUI(); }
if (Application.isPlaying && useUINavigation) { AddUINavigation(); }
else if (Application.isPlaying && !useUINavigation && targetButton == null)
{
targetButton = gameObject.AddComponent<Button>();
targetButton.transition = Selectable.Transition.None;
}
}
void Initialize()
{
#if UNITY_EDITOR
if (!Application.isPlaying) { return; }
#endif
if (ControllerManager.instance != null) { ControllerManager.instance.shopButtons.Add(this); }
if (UIManagerAudio.instance == null) { useSounds = false; }
if (animator == null) { animator = GetComponent<Animator>(); }
if (GetComponent<Image>() == null)
{
Image raycastImg = gameObject.AddComponent<Image>();
raycastImg.color = new Color(0, 0, 0, 0);
raycastImg.raycastTarget = true;
}
TriggerAnimation("Start");
if (useLocalization && !useCustomContent)
{
LocalizedObject mainLoc = GetComponent<LocalizedObject>();
if (mainLoc == null || !mainLoc.CheckLocalizationStatus()) { useLocalization = false; }
else
{
if (titleObj != null && !string.IsNullOrEmpty(titleLocalizationKey))
{
LocalizedObject titleLoc = titleObj.gameObject.GetComponent<LocalizedObject>();
if (titleLoc != null)
{
titleLoc.tableIndex = mainLoc.tableIndex;
titleLoc.localizationKey = titleLocalizationKey;
titleLoc.UpdateItem();
}
}
if (descriptionObj != null && !string.IsNullOrEmpty(descriptionLocalizationKey))
{
LocalizedObject descLoc = descriptionObj.gameObject.GetComponent<LocalizedObject>();
if (descLoc != null)
{
descLoc.tableIndex = mainLoc.tableIndex;
descLoc.localizationKey = descriptionLocalizationKey;
descLoc.UpdateItem();
}
}
// Change button text on language change
mainLoc.onLanguageChanged.AddListener(delegate
{
buttonTitle = mainLoc.GetKeyOutput(titleLocalizationKey);
buttonDescription = mainLoc.GetKeyOutput(descriptionLocalizationKey);
UpdateUI();
});
}
}
isInitialized = true;
}
public void UpdateUI()
{
if (enableIcon && iconObj != null) { iconObj.gameObject.SetActive(true); iconObj.sprite = buttonIcon; }
else if (iconObj != null) { iconObj.gameObject.SetActive(false); }
if (enableTitle && titleObj != null) { titleObj.gameObject.SetActive(true); titleObj.text = buttonTitle; }
else if (titleObj != null) { titleObj.gameObject.SetActive(false); }
if (enableDescription && descriptionObj != null) { descriptionObj.gameObject.SetActive(true); descriptionObj.text = buttonDescription; }
else if (descriptionObj != null)
{
descriptionObj.gameObject.SetActive(false);
if (Application.isPlaying && enableTitle && titleObj != null) { titleObj.transform.parent.gameObject.name = titleObj.gameObject.name + "_D"; }
}
if (!enablePrice && priceObj != null) { priceObj.transform.parent.gameObject.SetActive(false); }
else if (enablePrice && priceIconObj != null)
{
if (priceObj != null) { priceObj.transform.parent.gameObject.SetActive(true); priceObj.text = priceText; }
if (priceIconObj != null) { priceIconObj.sprite = priceIcon; }
}
if (!enableFilter && filterObj != null) { filterObj.gameObject.SetActive(false); }
else if (enableFilter && filterObj != null && filters.Count > 1)
{
filterObj.gameObject.SetActive(true);
if (Application.isPlaying && backgroundFilter == BackgroundFilter.Random) { filterObj.sprite = filters[Random.Range(0, filters.Count - 1)]; }
else if (filters.Count >= (int)backgroundFilter + 1) { filterObj.sprite = filters[(int)backgroundFilter]; }
}
UpdateState();
if (!Application.isPlaying || !gameObject.activeInHierarchy) { return; }
animator.enabled = true;
animator.SetTrigger("Start");
StopCoroutine("DisableAnimator");
StartCoroutine("DisableAnimator");
}
public void UpdateState()
{
if (purchaseButton == null || purchasedButton == null || purchasedIndicator == null)
return;
if (state == State.Default)
{
purchaseButton.gameObject.SetActive(true);
purchasedButton.gameObject.SetActive(false);
purchasedIndicator.gameObject.SetActive(false);
}
else if (state == State.Purchased)
{
purchaseButton.gameObject.SetActive(false);
purchasedButton.gameObject.SetActive(true);
purchasedIndicator.gameObject.SetActive(true);
}
}
public void SetState(State tempState)
{
state = tempState;
UpdateState();
}
public void Purchase()
{
if (state == State.Purchased)
return;
SetState(State.Purchased);
onPurchase.Invoke();
}
public void InitializePurchaseEvents()
{
if (purchaseButton == null)
{
Debug.LogError("<b>[Shop Button]</b> 'Purchase Button' is missing.", this);
return;
}
purchaseButton.onClick.RemoveAllListeners();
if (useModalWindow && purchaseModal != null)
{
onPurchaseClick.AddListener(delegate
{
purchaseModal.onConfirm.RemoveAllListeners();
purchaseModal.onConfirm.AddListener(Purchase);
purchaseModal.onConfirm.AddListener(purchaseModal.CloseWindow);
purchaseModal.OpenWindow();
});
}
purchaseButton.onClick.AddListener(onPurchaseClick.Invoke);
}
public void SetText(string text) { buttonTitle = text; UpdateUI(); }
public void SetIcon(Sprite icon) { buttonIcon = icon; UpdateUI(); }
public void SetPrice(string text) { priceText = text; UpdateUI(); }
public void SetInteractable(bool value) { isInteractable = value; }
public void AddUINavigation()
{
if (targetButton == null)
{
if (gameObject.GetComponent<Button>() == null) { targetButton = gameObject.AddComponent<Button>(); }
else { targetButton = GetComponent<Button>(); }
targetButton.transition = Selectable.Transition.None;
}
if (targetButton.navigation.mode == navigationMode)
return;
Navigation customNav = new Navigation();
customNav.mode = navigationMode;
if (navigationMode == Navigation.Mode.Vertical || navigationMode == Navigation.Mode.Horizontal) { customNav.wrapAround = wrapAround; }
else if (navigationMode == Navigation.Mode.Explicit) { StartCoroutine("InitUINavigation", customNav); return; }
targetButton.navigation = customNav;
}
public void DisableUINavigation()
{
if (targetButton != null)
{
Navigation customNav = new Navigation();
Navigation.Mode navMode = Navigation.Mode.None;
customNav.mode = navMode;
targetButton.navigation = customNav;
}
}
public void InvokeOnClick()
{
onClick.Invoke();
}
void TriggerAnimation(string triggername)
{
animator.enabled = true;
animator.ResetTrigger("Start");
animator.ResetTrigger("Normal");
animator.ResetTrigger("Highlighted");
animator.SetTrigger(triggername);
StopCoroutine("DisableAnimator");
StartCoroutine("DisableAnimator");
}
public void OnPointerClick(PointerEventData eventData)
{
if (!isInteractable || eventData.button != PointerEventData.InputButton.Left) { return; }
if (useSounds) { UIManagerAudio.instance.audioSource.PlayOneShot(UIManagerAudio.instance.UIManagerAsset.clickSound); }
// Invoke click actions
onClick.Invoke();
}
public void OnPointerEnter(PointerEventData eventData)
{
if (!isInteractable) { return; }
if (useSounds) { UIManagerAudio.instance.audioSource.PlayOneShot(UIManagerAudio.instance.UIManagerAsset.hoverSound); }
TriggerAnimation("Highlighted");
onHover.Invoke();
}
public void OnPointerExit(PointerEventData eventData)
{
if (!isInteractable)
return;
TriggerAnimation("Normal");
onLeave.Invoke();
}
public void OnSelect(BaseEventData eventData)
{
if (!isInteractable) { return; }
if (useSounds) { UIManagerAudio.instance.audioSource.PlayOneShot(UIManagerAudio.instance.UIManagerAsset.hoverSound); }
TriggerAnimation("Highlighted");
onSelect.Invoke();
}
public void OnDeselect(BaseEventData eventData)
{
if (!isInteractable)
return;
TriggerAnimation("Normal");
onDeselect.Invoke();
}
public void OnSubmit(BaseEventData eventData)
{
if (!isInteractable) { return; }
if (useSounds) { UIManagerAudio.instance.audioSource.PlayOneShot(UIManagerAudio.instance.UIManagerAsset.clickSound); }
if (EventSystem.current.currentSelectedGameObject != gameObject) { TriggerAnimation("Normal"); }
onClick.Invoke();
}
IEnumerator InitUINavigation(Navigation nav)
{
yield return new WaitForSecondsRealtime(0.1f);
if (selectOnUp != null) { nav.selectOnUp = selectOnUp.GetComponent<Selectable>(); }
if (selectOnDown != null) { nav.selectOnDown = selectOnDown.GetComponent<Selectable>(); }
if (selectOnLeft != null) { nav.selectOnLeft = selectOnLeft.GetComponent<Selectable>(); }
if (selectOnRight != null) { nav.selectOnRight = selectOnRight.GetComponent<Selectable>(); }
targetButton.navigation = nav;
}
IEnumerator DisableAnimator()
{
yield return new WaitForSecondsRealtime(cachedStateLength);
animator.enabled = false;
}
}
}