Files
bansonic_beta_main/Assets/_eqpmtSys/equipSystems/chooseSkillPrefab.cs
T

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();
}
}