2025-12-03 17:26:55 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEngine.EventSystems;
|
|
|
|
|
|
2025-12-09 15:08:41 +08:00
|
|
|
namespace UnityEngine.UI
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-09 15:08:41 +08:00
|
|
|
[Serializable]
|
|
|
|
|
public class TransitionData
|
|
|
|
|
{
|
|
|
|
|
public Graphic targetGraphic;
|
|
|
|
|
public Selectable.Transition transition = Selectable.Transition.ColorTint;
|
|
|
|
|
public ColorBlock colors = ColorBlock.defaultColorBlock;
|
|
|
|
|
public SpriteState spriteState;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
public class UXSelectable : Selectable
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
[SerializeField] private List<TransitionData> m_ChildTransitions = new();
|
2025-12-10 11:16:55 +08:00
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
void StartChildColorTween(TransitionData transitionData, Color targetColor, bool instant)
|
2025-12-09 15:08:41 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
if (transitionData.targetGraphic == null)
|
2025-12-03 17:26:55 +08:00
|
|
|
return;
|
2025-12-19 20:26:22 +08:00
|
|
|
transitionData.targetGraphic.CrossFadeColor(targetColor, instant ? 0f : transitionData.colors.fadeDuration, true, true);
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
void DoChildSpriteSwap(TransitionData transitionData, Sprite newSprite)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
if (transitionData.targetGraphic == null)
|
2025-12-03 17:26:55 +08:00
|
|
|
return;
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
if (transitionData.targetGraphic is Image img)
|
|
|
|
|
img.overrideSprite = newSprite;
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
2025-12-19 20:26:22 +08:00
|
|
|
#if UNITY_EDITOR
|
|
|
|
|
protected override void OnValidate()
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
if (isActiveAndEnabled)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
for (int i = 0; i < m_ChildTransitions.Count; i++)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
DoChildSpriteSwap(m_ChildTransitions[i], null);
|
|
|
|
|
StartChildColorTween(m_ChildTransitions[i], Color.white, true);
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
2025-12-09 15:08:41 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
base.OnValidate();
|
2025-12-09 15:08:41 +08:00
|
|
|
}
|
2025-12-19 20:26:22 +08:00
|
|
|
#endif
|
2025-12-09 15:08:41 +08:00
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
protected override void InstantClearState()
|
2025-12-09 15:08:41 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
base.InstantClearState();
|
|
|
|
|
for (int i = 0; i < m_ChildTransitions.Count; i++)
|
2025-12-09 15:08:41 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
switch (transition)
|
|
|
|
|
{
|
|
|
|
|
case Transition.ColorTint:
|
|
|
|
|
StartChildColorTween(m_ChildTransitions[i], Color.white, true);
|
|
|
|
|
break;
|
|
|
|
|
case Transition.SpriteSwap:
|
|
|
|
|
DoChildSpriteSwap(m_ChildTransitions[i], null);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2025-12-09 15:08:41 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
protected override void DoStateTransition(SelectionState state, bool instant)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
base.DoStateTransition(state, instant);
|
2025-12-03 17:26:55 +08:00
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
for (int i = 0; i < m_ChildTransitions.Count; i++)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
TransitionData transitionData = m_ChildTransitions[i];
|
|
|
|
|
Color tintColor;
|
|
|
|
|
Sprite transitionSprite;
|
|
|
|
|
switch (state)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
case SelectionState.Normal:
|
|
|
|
|
tintColor = transitionData.colors.normalColor;
|
|
|
|
|
transitionSprite = null;
|
|
|
|
|
break;
|
|
|
|
|
case SelectionState.Highlighted:
|
|
|
|
|
tintColor = transitionData.colors.highlightedColor;
|
|
|
|
|
transitionSprite = transitionData.spriteState.highlightedSprite;
|
|
|
|
|
break;
|
|
|
|
|
case SelectionState.Pressed:
|
|
|
|
|
tintColor = transitionData.colors.pressedColor;
|
|
|
|
|
transitionSprite = transitionData.spriteState.pressedSprite;
|
|
|
|
|
break;
|
|
|
|
|
case SelectionState.Selected:
|
|
|
|
|
tintColor = transitionData.colors.selectedColor;
|
|
|
|
|
transitionSprite = transitionData.spriteState.selectedSprite;
|
|
|
|
|
break;
|
|
|
|
|
case SelectionState.Disabled:
|
|
|
|
|
tintColor = transitionData.colors.disabledColor;
|
|
|
|
|
transitionSprite = transitionData.spriteState.disabledSprite;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
tintColor = Color.black;
|
|
|
|
|
transitionSprite = null;
|
|
|
|
|
break;
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
|
|
|
|
|
2025-12-19 20:26:22 +08:00
|
|
|
switch (transition)
|
2025-12-03 17:26:55 +08:00
|
|
|
{
|
2025-12-19 20:26:22 +08:00
|
|
|
case Transition.ColorTint:
|
|
|
|
|
StartChildColorTween(transitionData, tintColor * transitionData.colors.colorMultiplier, instant);
|
|
|
|
|
break;
|
|
|
|
|
case Transition.SpriteSwap:
|
|
|
|
|
DoChildSpriteSwap(transitionData, transitionSprite);
|
|
|
|
|
break;
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
|
|
|
|
}
|
2025-12-05 19:03:35 +08:00
|
|
|
}
|
2025-12-22 11:28:47 +08:00
|
|
|
|
|
|
|
|
public override Selectable FindSelectableOnLeft()
|
|
|
|
|
{
|
|
|
|
|
if (navigation.mode == Navigation.Mode.Explicit && navigation.selectOnLeft != null && navigation.selectOnLeft.interactable)
|
|
|
|
|
{
|
|
|
|
|
return navigation.selectOnLeft;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((navigation.mode & Navigation.Mode.Horizontal) != 0)
|
|
|
|
|
{
|
|
|
|
|
return FindSelectable(transform.rotation * Vector3.left);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Selectable FindSelectableOnRight()
|
|
|
|
|
{
|
|
|
|
|
if (navigation.mode == Navigation.Mode.Explicit && navigation.selectOnRight != null && navigation.selectOnRight.interactable)
|
|
|
|
|
{
|
|
|
|
|
return navigation.selectOnRight;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((navigation.mode & Navigation.Mode.Horizontal) != 0)
|
|
|
|
|
{
|
|
|
|
|
return FindSelectable(transform.rotation * Vector3.right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Selectable FindSelectableOnUp()
|
|
|
|
|
{
|
|
|
|
|
if (navigation.mode == Navigation.Mode.Explicit && navigation.selectOnUp != null && navigation.selectOnUp.interactable)
|
|
|
|
|
{
|
|
|
|
|
return navigation.selectOnUp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((navigation.mode & Navigation.Mode.Vertical) != 0)
|
|
|
|
|
{
|
|
|
|
|
return FindSelectable(transform.rotation * Vector3.up);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Selectable FindSelectableOnDown()
|
|
|
|
|
{
|
|
|
|
|
if (navigation.mode == Navigation.Mode.Explicit && navigation.selectOnDown != null && navigation.selectOnDown.interactable)
|
|
|
|
|
{
|
|
|
|
|
return navigation.selectOnDown;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((navigation.mode & Navigation.Mode.Vertical) != 0)
|
|
|
|
|
{
|
|
|
|
|
return FindSelectable(transform.rotation * Vector3.down);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2025-12-03 17:26:55 +08:00
|
|
|
}
|
|
|
|
|
}
|