using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; namespace DuloGames.UI { [AddComponentMenu("UI/Icon Slots/Equip Receiver", 46), ExecuteInEditMode] public class UIEquipReceiver : UIBehaviour, IEventSystemHandler, IDropHandler, IPointerEnterHandler, IPointerExitHandler { public enum HintState { Shown, Hidden } [SerializeField] private Transform m_SlotsContainer; [SerializeField] private Text m_HintText; [SerializeField] private bool m_Fading = true; [SerializeField] private float m_FadeDuration = 0.15f; [SerializeField] private HintState m_HintState = HintState.Hidden; protected override void Start() { // Make sure we have a container if (Application.isPlaying && this.m_SlotsContainer == null) this.m_SlotsContainer = this.transform; // Prepare the hint text starting state if (this.m_HintText != null) this.m_HintText.canvasRenderer.SetAlpha(this.m_HintState == HintState.Hidden ? 0f : 1f); } #if UNITY_EDITOR protected override void OnValidate() { if (this.m_HintText != null) this.m_HintText.canvasRenderer.SetAlpha(this.m_HintState == HintState.Hidden ? 0f : 1f); } #endif /// /// Gets a slot within it's children by the specified type. /// /// The slot by type. /// Type. public UIEquipSlot GetSlotByType(UIEquipmentType type) { UIEquipSlot[] slots = this.m_SlotsContainer.GetComponentsInChildren(); // Find a suitable slot for the given type foreach (UIEquipSlot slot in slots) { if (slot.enabled && slot.gameObject.activeSelf && slot.equipType == type) return slot; } return null; } /// /// Raises the pointer enter event. /// /// Event data. public void OnPointerEnter(PointerEventData eventData) { if (this.m_HintText == null) return; // Check if we are dragging if (eventData.dragging) { // Try getting slot base component from the selected object UISlotBase slotBase = this.ExtractSlot(eventData); // If we have a slot, we should show the hint if (slotBase != null) { // Show the hint if (this.m_Fading) { this.m_HintText.CrossFadeAlpha(1f, this.m_FadeDuration, true); } else { this.m_HintText.canvasRenderer.SetAlpha(1f); } // Set the hint state this.m_HintState = HintState.Shown; } } } /// /// Hides the hint text if it's visible. /// private void HideHint() { if (this.m_HintState == HintState.Hidden) return; // Hide the hint if (this.m_Fading) { this.m_HintText.CrossFadeAlpha(0f, this.m_FadeDuration, true); } else { this.m_HintText.canvasRenderer.SetAlpha(0f); } this.m_HintState = HintState.Hidden; } /// /// Raises the pointer exit event. /// /// Event data. public void OnPointerExit(PointerEventData eventData) { if (this.m_HintText == null) return; // Hide the hint this.HideHint(); } /// /// Raises the drop event. /// /// Event data. public void OnDrop(PointerEventData eventData) { if (eventData.pointerPress == null) return; // Try getting slot base component from the selected object UISlotBase slotBase = this.ExtractSlot(eventData); // Check if we have a slot if (slotBase == null) return; // Determine the type of slot we are dropping here if (slotBase is UIItemSlot) { UIItemSlot itemSlot = (slotBase as UIItemSlot); // Make sure the slot we are dropping is valid and assigned if (itemSlot != null && itemSlot.IsAssigned()) { // Try finding a suitable slot to equip UIEquipSlot equipSlot = this.GetSlotByType(itemSlot.GetItemInfo().EquipType); if (equipSlot != null) { // Use the drop event to handle equip equipSlot.OnDrop(eventData); // Hide the hint this.HideHint(); // Break out of the method return; } } } } /// /// Extracts a base slot based on the event data. /// /// The slot. /// Event data. private UISlotBase ExtractSlot(PointerEventData eventData) { if (eventData.pointerPress == null) return null; // Try getting slot base component from the selected object UISlotBase slotBase = eventData.pointerPress.GetComponent(); // Check if we failed to get a slot from the pressed game object directly if (slotBase == null) slotBase = eventData.pointerPress.GetComponentInChildren(); return slotBase; } } }