405 lines
15 KiB
C#
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;
|
|
}
|
|
}
|
|
} |