307 lines
8.5 KiB
C#
307 lines
8.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UnityEngine.EventSystems;
|
|
using System.Collections;
|
|
|
|
public class lrPrefab : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
|
|
{
|
|
[Header("uis")]
|
|
public Text levelName;
|
|
public Image levelid_btm;
|
|
public Image statusImg;
|
|
public Text thisSkillName;
|
|
|
|
[Header("state visuals")]
|
|
public Sprite lockedStatusSprite;
|
|
public Color selectableSkillNameColor = Color.white;
|
|
public Color unavailableSkillNameColor = Color.gray;
|
|
|
|
[Header("desOBJ")]
|
|
public GameObject descriptionPrefab;
|
|
public float descriptionOffsetX = 80f;
|
|
|
|
[Header("material")]
|
|
public Material grayScale_mtr;
|
|
|
|
[Header("preselect pulse")]
|
|
public float preselectPulseDuration = 0.8f;
|
|
|
|
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 Coroutine preselectPulseCoroutine;
|
|
private GameObject spawnedDescription;
|
|
private bool visualDefaultsCached = false;
|
|
private Sprite defaultStatusSprite;
|
|
private Material defaultStatusMaterial;
|
|
private Material defaultLevelIdMaterial;
|
|
|
|
public void Bind(uLevel_skills ownerController, userLevel_skills_SO sourceSo, int index, userLevel_skills_SO.UserLevelSkillEntry entry, bool unlocked)
|
|
{
|
|
CacheVisualDefaults();
|
|
|
|
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);
|
|
thisSkillName.color = isUnlocked ? selectableSkillNameColor : unavailableSkillNameColor;
|
|
}
|
|
|
|
if (statusImg == null)
|
|
return;
|
|
|
|
bool isPreselected = owner != null && owner.IsSkillPreselected(boundIndex);
|
|
ApplyStatusState(isPreselected);
|
|
}
|
|
|
|
private void ApplyStatusState(bool isPreselected)
|
|
{
|
|
if (statusImg == null)
|
|
return;
|
|
|
|
StopPreselectPulse();
|
|
|
|
if (!isUnlocked)
|
|
{
|
|
SetStatusSprite(lockedStatusSprite != null ? lockedStatusSprite : defaultStatusSprite);
|
|
SetStatusMaterial(defaultStatusMaterial);
|
|
SetLevelIdMaterial(grayScale_mtr);
|
|
SetStatusAlpha(1f);
|
|
return;
|
|
}
|
|
|
|
SetStatusSprite(defaultStatusSprite);
|
|
|
|
if (isPreselected)
|
|
{
|
|
SetStatusMaterial(defaultStatusMaterial);
|
|
SetLevelIdMaterial(defaultLevelIdMaterial);
|
|
StartPreselectPulse();
|
|
return;
|
|
}
|
|
|
|
if (boundEntry != null && boundEntry.isEnabled)
|
|
{
|
|
SetStatusMaterial(defaultStatusMaterial);
|
|
SetLevelIdMaterial(defaultLevelIdMaterial);
|
|
SetStatusAlpha(1f);
|
|
return;
|
|
}
|
|
|
|
SetStatusMaterial(grayScale_mtr);
|
|
SetLevelIdMaterial(defaultLevelIdMaterial);
|
|
SetStatusAlpha(1f);
|
|
}
|
|
|
|
private void CacheVisualDefaults()
|
|
{
|
|
if (visualDefaultsCached)
|
|
return;
|
|
|
|
visualDefaultsCached = true;
|
|
defaultStatusSprite = statusImg != null ? statusImg.sprite : null;
|
|
defaultStatusMaterial = statusImg != null ? statusImg.material : null;
|
|
defaultLevelIdMaterial = levelid_btm != null ? levelid_btm.material : null;
|
|
}
|
|
|
|
private void SetStatusSprite(Sprite spriteToApply)
|
|
{
|
|
if (statusImg == null)
|
|
return;
|
|
|
|
statusImg.sprite = spriteToApply;
|
|
}
|
|
|
|
private void SetStatusMaterial(Material materialToApply)
|
|
{
|
|
if (statusImg == null)
|
|
return;
|
|
|
|
statusImg.material = materialToApply;
|
|
}
|
|
|
|
private void SetLevelIdMaterial(Material materialToApply)
|
|
{
|
|
if (levelid_btm == null)
|
|
return;
|
|
|
|
levelid_btm.material = materialToApply;
|
|
}
|
|
|
|
private void SetStatusAlpha(float alpha)
|
|
{
|
|
if (statusImg == null)
|
|
return;
|
|
|
|
Color color = statusImg.color;
|
|
color.a = Mathf.Clamp01(alpha);
|
|
statusImg.color = color;
|
|
}
|
|
|
|
private void StartPreselectPulse()
|
|
{
|
|
if (!isActiveAndEnabled || statusImg == null)
|
|
return;
|
|
|
|
preselectPulseCoroutine = StartCoroutine(PreselectPulseRoutine());
|
|
}
|
|
|
|
private void StopPreselectPulse()
|
|
{
|
|
if (preselectPulseCoroutine != null)
|
|
{
|
|
StopCoroutine(preselectPulseCoroutine);
|
|
preselectPulseCoroutine = null;
|
|
}
|
|
}
|
|
|
|
private IEnumerator PreselectPulseRoutine()
|
|
{
|
|
float duration = Mathf.Max(0.05f, preselectPulseDuration);
|
|
float elapsed = 0f;
|
|
|
|
while (true)
|
|
{
|
|
elapsed += Time.unscaledDeltaTime;
|
|
float normalizedTime = Mathf.PingPong(elapsed / duration, 1f);
|
|
SetStatusAlpha(Mathf.Lerp(0.5f, 1f, normalizedTime));
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
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<esDesPrefab>();
|
|
if (detail != null)
|
|
detail.Bind(boundEntry.skillName, boundEntry.skillIcon, boundEntry.skillDescription, boundEntry.skillSummary);
|
|
|
|
RectTransform spawnedRect = spawnedDescription.GetComponent<RectTransform>();
|
|
if (spawnedRect == null)
|
|
return;
|
|
|
|
Canvas canvas = root.GetComponentInParent<Canvas>();
|
|
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<Canvas>();
|
|
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()
|
|
{
|
|
StopPreselectPulse();
|
|
|
|
if (hoverCoroutine != null)
|
|
{
|
|
StopCoroutine(hoverCoroutine);
|
|
hoverCoroutine = null;
|
|
}
|
|
|
|
HideDescription();
|
|
}
|
|
}
|