neon_run/Assets/Scripts/ImageToggle.cs
2025-12-09 12:37:58 +05:30

141 lines
3.9 KiB
C#

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
using UnityEngine.Events;
[RequireComponent(typeof(EventTrigger))]
public class ImageToggle : MonoBehaviour
{
public UnityEvent<bool> onToggle;
[SerializeField]
private bool m_isOn = false;
public bool isOn{
get{
return m_isOn;
}
set{
Toggle(value);
}
}
[SerializeField]
private Image image;
public Color onColor = Color.white;
public Color offColor = Color.gray;
[Header("Swap")]
public Sprite onSprite;
public Sprite offSprite;
[Header("Tween Settings")]
public float tweenDuration = 0.2f;
public Ease tweenEase = Ease.OutQuad;
public float enabledScale = 1f;
public float disabledScale = 0.9f;
public float hoverScale = 1.1f;
private Tweener colorTween;
private EventTrigger eventTrigger;
void OnValidate(){
if(image == null){
image = GetComponent<Image>();
}else{
UpdateImageColor();
}
}
void Awake(){
// Ensure we have an image reference and set initial color instantly
if(image == null){
image = GetComponent<Image>();
}
UpdateImageColor();
}
void Start()
{
eventTrigger = GetComponent<EventTrigger>();
EventTrigger.Entry entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerDown;
entry.callback.AddListener((data) => {
Toggle(!m_isOn);
});
eventTrigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerEnter;
entry.callback.AddListener((data) => {
float targetScale = (m_isOn ? enabledScale : disabledScale) * hoverScale;
transform.DOScale(targetScale * hoverScale, tweenDuration).SetEase(tweenEase).SetUpdate(true);
});
eventTrigger.triggers.Add(entry);
entry = new EventTrigger.Entry();
entry.eventID = EventTriggerType.PointerExit;
entry.callback.AddListener((data) => {
float targetScale = m_isOn ? enabledScale : disabledScale;
transform.DOScale(targetScale, tweenDuration).SetEase(tweenEase).SetUpdate(true);
});
eventTrigger.triggers.Add(entry);
}
public void Toggle(bool value){
m_isOn = value;
AnimateImageColor();
onToggle.Invoke(value);
}
void UpdateImageColor(){
image.color = m_isOn ? onColor : offColor;
image.transform.localScale = Vector3.one * (m_isOn ? enabledScale : disabledScale);
// Update sprite if sprites are assigned
if(onSprite != null && offSprite != null){
image.sprite = m_isOn ? onSprite : offSprite;
}
}
void AnimateImageColor(){
if(image == null) return;
// Kill any existing tween on this image's color to avoid conflicts
if(colorTween != null && colorTween.IsActive()){
colorTween.Kill();
}
Color targetColor = m_isOn ? onColor : offColor;
// Update sprite if sprites are assigned (sprite changes instantly, no animation)
if(onSprite != null && offSprite != null){
image.sprite = m_isOn ? onSprite : offSprite;
}
// If duration is 0 or negative, just snap to the color
if(tweenDuration <= 0f){
image.color = targetColor;
return;
}
colorTween = image.DOColor(targetColor, tweenDuration)
.SetEase(tweenEase).SetUpdate(true);
AnimateImageScale();
}
void AnimateImageScale(){
if(image == null) return;
float targetScale = m_isOn ? enabledScale : disabledScale;
image.transform.DOScale(targetScale, tweenDuration).SetEase(tweenEase).SetUpdate(true);
}
}