using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; using System.Collections; public class lrPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler { [Header("sprite")] public Sprite enableSprite; public Sprite availableSprite; public Sprite lockedSprite; public Sprite unknownSprite; public Sprite preSelectSprite; [Header("uis")] public Text levelName; public Image statusImg; public Text thisSkillName; [Header("desOBJ")] public GameObject descriptionPrefab; public float descriptionOffsetX = 80f; private uLevel_skills owner; private userLevel_skills_SO ownerSo; private userLevel_skills_SO.UserLevelSkillEntry boundEntry; private int boundIndex = -1; private bool isUnlocked = false; private Coroutine hoverCoroutine; private GameObject spawnedDescription; public void Bind(uLevel_skills ownerController, userLevel_skills_SO sourceSo, int index, userLevel_skills_SO.UserLevelSkillEntry entry, bool unlocked) { owner = ownerController; ownerSo = sourceSo; boundIndex = index; boundEntry = entry; isUnlocked = unlocked; if (levelName != null) levelName.text = entry != null ? entry.userLevel.ToString() : string.Empty; RefreshVisualState(); } public void RefreshVisualState() { if (owner != null && boundEntry != null) isUnlocked = owner.IsSkillUnlocked(boundEntry); if (boundEntry == null) return; bool revealLockedSkills = PlayerSkillService.IsSkillEnabled(7); bool shouldHideLockedSkillInfo = !isUnlocked && !revealLockedSkills; if (thisSkillName != null) { thisSkillName.text = shouldHideLockedSkillInfo ? "?????" : (boundEntry.skillName ?? string.Empty); } if (statusImg == null) return; if (owner != null && owner.IsSkillPreselected(boundIndex)) statusImg.sprite = preSelectSprite != null ? preSelectSprite : availableSprite; else if (boundEntry.isEnabled) statusImg.sprite = enableSprite; else if (isUnlocked) statusImg.sprite = availableSprite; else if (shouldHideLockedSkillInfo) statusImg.sprite = unknownSprite != null ? unknownSprite : lockedSprite; else statusImg.sprite = lockedSprite; } public void OnPointerEnter(PointerEventData eventData) { if (boundEntry == null || descriptionPrefab == null) return; if (!isUnlocked && !PlayerSkillService.IsSkillEnabled(7)) return; if (hoverCoroutine != null) StopCoroutine(hoverCoroutine); hoverCoroutine = StartCoroutine(ShowDescriptionAfterDelay()); } public void OnPointerExit(PointerEventData eventData) { if (hoverCoroutine != null) { StopCoroutine(hoverCoroutine); hoverCoroutine = null; } HideDescription(); } public void OnPointerClick(PointerEventData eventData) { if (owner == null || boundIndex < 0) return; owner.ToggleSkill(boundIndex); } private IEnumerator ShowDescriptionAfterDelay() { yield return new WaitForSeconds(0.5f); hoverCoroutine = null; ShowDescription(); } private void ShowDescription() { if (spawnedDescription != null || descriptionPrefab == null || boundEntry == null) return; RectTransform root = ResolveDescriptionRoot(); if (root == null) return; spawnedDescription = Instantiate(descriptionPrefab, root); spawnedDescription.SetActive(true); spawnedDescription.transform.SetAsLastSibling(); esDesPrefab detail = spawnedDescription.GetComponent(); if (detail != null) detail.Bind(boundEntry.skillName, boundEntry.skillIcon, boundEntry.skillDescription, boundEntry.skillSummary); RectTransform spawnedRect = spawnedDescription.GetComponent(); if (spawnedRect == null) return; Canvas canvas = root.GetComponentInParent(); Camera eventCamera = null; if (canvas != null && canvas.renderMode != RenderMode.ScreenSpaceOverlay) eventCamera = canvas.worldCamera; Vector2 localPoint; RectTransformUtility.ScreenPointToLocalPointInRectangle(root, Input.mousePosition, eventCamera, out localPoint); localPoint.x += descriptionOffsetX; spawnedRect.anchoredPosition = localPoint; } private RectTransform ResolveDescriptionRoot() { Canvas canvas = GetComponentInParent(); if (canvas == null) return null; Canvas rootCanvas = canvas.rootCanvas != null ? canvas.rootCanvas : canvas; return rootCanvas.transform as RectTransform; } private void HideDescription() { if (spawnedDescription == null) return; if (Application.isPlaying) Destroy(spawnedDescription); else DestroyImmediate(spawnedDescription); spawnedDescription = null; } private void OnDisable() { if (hoverCoroutine != null) { StopCoroutine(hoverCoroutine); hoverCoroutine = null; } HideDescription(); } }