256 lines
6.7 KiB
C#
256 lines
6.7 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
|
public class chooseSkillPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler
|
|
{
|
|
public Image this_skillProfile;
|
|
public Text this_skillName;
|
|
public Button this_skillDesButton;
|
|
public GameObject sskilldetialPrefab;
|
|
public Vector2 detailPrefabOffset = new Vector2(20f, 0f);
|
|
public float hoverDetailDelay = 0.25f;
|
|
|
|
private int boundSkillGroupId;
|
|
private string boundDescription;
|
|
private Sprite boundIcon;
|
|
private string boundName;
|
|
private GameObject spawnedDetail;
|
|
private Coroutine hoverDetailCoroutine;
|
|
private bool detailPinnedByButton;
|
|
private int detailOpenedFrame = -1;
|
|
|
|
public void Bind(int skillGroupId, string skillName, Sprite skillIcon, string skillDescription, System.Action<int> onSelected)
|
|
{
|
|
boundSkillGroupId = skillGroupId;
|
|
boundName = skillName ?? string.Empty;
|
|
boundIcon = skillIcon;
|
|
boundDescription = skillDescription ?? string.Empty;
|
|
|
|
if (this_skillName != null)
|
|
{
|
|
this_skillName.text = boundName;
|
|
}
|
|
|
|
if (this_skillProfile != null)
|
|
{
|
|
this_skillProfile.sprite = boundIcon;
|
|
this_skillProfile.enabled = boundIcon != null;
|
|
}
|
|
|
|
Button rootButton = GetComponent<Button>();
|
|
if (rootButton != null)
|
|
{
|
|
rootButton.onClick.RemoveAllListeners();
|
|
rootButton.onClick.AddListener(() => onSelected?.Invoke(boundSkillGroupId));
|
|
}
|
|
|
|
if (this_skillDesButton != null)
|
|
{
|
|
this_skillDesButton.onClick.RemoveAllListeners();
|
|
this_skillDesButton.onClick.AddListener(TogglePinnedDetail);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (!detailPinnedByButton || spawnedDetail == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (detailOpenedFrame == Time.frameCount)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!Input.GetMouseButtonDown(0))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector2 screenPoint = Input.mousePosition;
|
|
if (IsPointerInside(screenPoint))
|
|
{
|
|
return;
|
|
}
|
|
|
|
CloseDetail();
|
|
}
|
|
|
|
public void OnPointerEnter(PointerEventData eventData)
|
|
{
|
|
if (detailPinnedByButton)
|
|
{
|
|
return;
|
|
}
|
|
|
|
StopHoverCoroutine();
|
|
hoverDetailCoroutine = StartCoroutine(ShowHoverDetailDelayed());
|
|
}
|
|
|
|
public void OnPointerExit(PointerEventData eventData)
|
|
{
|
|
StopHoverCoroutine();
|
|
|
|
if (!detailPinnedByButton)
|
|
{
|
|
CloseDetail();
|
|
}
|
|
}
|
|
|
|
private System.Collections.IEnumerator ShowHoverDetailDelayed()
|
|
{
|
|
yield return new WaitForSeconds(hoverDetailDelay);
|
|
|
|
if (!detailPinnedByButton)
|
|
{
|
|
ShowDetail(false);
|
|
}
|
|
}
|
|
|
|
private void TogglePinnedDetail()
|
|
{
|
|
StopHoverCoroutine();
|
|
|
|
if (detailPinnedByButton)
|
|
{
|
|
CloseDetail();
|
|
return;
|
|
}
|
|
|
|
ShowDetail(true);
|
|
}
|
|
|
|
private void ShowDetail(bool pinnedByButton)
|
|
{
|
|
if (sskilldetialPrefab == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (spawnedDetail != null)
|
|
{
|
|
Destroy(spawnedDetail);
|
|
spawnedDetail = null;
|
|
}
|
|
|
|
detailPinnedByButton = pinnedByButton;
|
|
detailOpenedFrame = Time.frameCount;
|
|
|
|
Transform parent = ResolveDetailParent();
|
|
spawnedDetail = Instantiate(sskilldetialPrefab, parent);
|
|
spawnedDetail.transform.SetAsLastSibling();
|
|
|
|
RectTransform selfRect = transform as RectTransform;
|
|
RectTransform detailRect = spawnedDetail.transform as RectTransform;
|
|
RectTransform parentRect = parent as RectTransform;
|
|
if (selfRect != null && detailRect != null && parentRect != null)
|
|
{
|
|
Canvas canvas = parent.GetComponentInParent<Canvas>();
|
|
Camera eventCamera = null;
|
|
if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
|
|
{
|
|
eventCamera = canvas.worldCamera;
|
|
}
|
|
|
|
Vector3 worldPoint = selfRect.TransformPoint(new Vector3(selfRect.rect.xMax, selfRect.rect.center.y, 0f));
|
|
RectTransformUtility.ScreenPointToLocalPointInRectangle(
|
|
parentRect,
|
|
RectTransformUtility.WorldToScreenPoint(eventCamera, worldPoint),
|
|
eventCamera,
|
|
out Vector2 localPoint);
|
|
detailRect.anchoredPosition = localPoint + detailPrefabOffset;
|
|
}
|
|
|
|
esDesPrefab detail = spawnedDetail.GetComponent<esDesPrefab>();
|
|
if (detail != null)
|
|
{
|
|
detail.Bind(boundName, boundIcon, boundDescription);
|
|
}
|
|
}
|
|
|
|
private Transform ResolveDetailParent()
|
|
{
|
|
Canvas canvas = GetComponentInParent<Canvas>();
|
|
if (canvas != null && canvas.rootCanvas != null)
|
|
{
|
|
return canvas.rootCanvas.transform;
|
|
}
|
|
|
|
if (transform.root != null)
|
|
{
|
|
return transform.root;
|
|
}
|
|
|
|
return transform;
|
|
}
|
|
|
|
private bool IsPointerInside(Vector2 screenPoint)
|
|
{
|
|
if (IsScreenPointInside(transform as RectTransform, screenPoint))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (this_skillDesButton != null && IsScreenPointInside(this_skillDesButton.transform as RectTransform, screenPoint))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (spawnedDetail != null && IsScreenPointInside(spawnedDetail.transform as RectTransform, screenPoint))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool IsScreenPointInside(RectTransform rectTransform, Vector2 screenPoint)
|
|
{
|
|
if (rectTransform == null || !rectTransform.gameObject.activeInHierarchy)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Canvas canvas = rectTransform.GetComponentInParent<Canvas>();
|
|
Camera eventCamera = null;
|
|
if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay)
|
|
{
|
|
eventCamera = canvas.worldCamera;
|
|
}
|
|
|
|
return RectTransformUtility.RectangleContainsScreenPoint(rectTransform, screenPoint, eventCamera);
|
|
}
|
|
|
|
private void StopHoverCoroutine()
|
|
{
|
|
if (hoverDetailCoroutine == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
StopCoroutine(hoverDetailCoroutine);
|
|
hoverDetailCoroutine = null;
|
|
}
|
|
|
|
private void CloseDetail()
|
|
{
|
|
detailPinnedByButton = false;
|
|
detailOpenedFrame = -1;
|
|
|
|
if (spawnedDetail != null)
|
|
{
|
|
Destroy(spawnedDetail);
|
|
spawnedDetail = null;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
StopHoverCoroutine();
|
|
CloseDetail();
|
|
}
|
|
}
|