using System; using UnityEngine; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.Serialization; using UnityEngine.UI; namespace UVC.UI.Buttons { /// /// 이미지 color를 변경하여 버튼과 같은 UI 요소에 시각적 피드백을 제공하는 이미지 버튼입니다. /// public class ImageButton : Image, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler { [SerializeField] private Color originalColor = Color.white; // 기본 상태일 때의 색상 [SerializeField] private Color hoverColor = Color.gray; // 마우스 포인터가 위에 있을 때의 색상 [SerializeField] private Color clickColor = Color.gray; // 클릭했을 때의 색상 [SerializeField] private Color disabledColor = Color.gray; // 비활성화 상태일 때의 색상 [SerializeField] private bool interactable = true; public bool Interactable { get => interactable; set { if (interactable == value) return; interactable = value; raycastTarget = value; // 상호 작용 가능 상태에 따라 raycastTarget 설정 color = value ? originalColor : disabledColor; } } [Serializable] /// /// 버튼 클릭 이벤트에 대한 함수 정의. /// public class ButtonClickedEvent : UnityEvent { } // onClick 이벤트는 인스펙터에 노출되며, 버튼 클릭 시 호출될 함수를 등록할 수 있습니다. [FormerlySerializedAs("onClick")] [SerializeField] private ButtonClickedEvent m_OnClick = new ButtonClickedEvent(); /// /// 버튼을 클릭할 때마다 호출되는 UnityEvent입니다. /// public ButtonClickedEvent onClick { get { return m_OnClick; } set { m_OnClick = value; } } protected override void Awake() { base.Awake(); // 초기화 시 Interactable 프로퍼티를 통해 색상과 raycastTarget을 설정합니다. raycastTarget = interactable; color = interactable ? originalColor : disabledColor; } /// /// 포인터가 버튼을 눌렀을 때 호출됩니다. /// public virtual void OnPointerDown(PointerEventData eventData) { if (Interactable) { color = clickColor; // 클릭 시 컬러 변경 } } /// /// 포인터가 버튼 영역에 들어왔을 때 호출됩니다. /// public virtual void OnPointerEnter(PointerEventData eventData) { if (Interactable) { color = hoverColor; // 마우스 오버 시 컬러 변경 } } /// /// 포인터가 버튼 영역을 벗어났을 때 호출됩니다. /// public virtual void OnPointerExit(PointerEventData eventData) { // 상호작용 가능 여부와 관계없이 포인터가 나가면 상태에 맞는 기본 색상으로 돌아갑니다. color = interactable ? originalColor : disabledColor; } /// /// 포인터가 버튼에서 떼어졌을 때 호출됩니다. /// public virtual void OnPointerUp(PointerEventData eventData) { if (Interactable) { color = hoverColor; // 클릭 후 원래 컬러로 변경 } } /// /// 버튼 클릭이 완료되었을 때 호출됩니다. (PointerDown과 PointerUp이 같은 대상에서 발생) /// public virtual void OnPointerClick(PointerEventData eventData) { // 왼쪽 마우스 버튼 클릭이 아니면 무시합니다. if (eventData.button != PointerEventData.InputButton.Left) return; Press(); } /// /// 내부적으로 클릭 이벤트를 실행합니다. /// private void Press() { // 컴포넌트가 활성화 상태가 아니거나 상호작용 불가능하면 이벤트를 호출하지 않습니다. if (!IsActive() || !interactable) return; m_OnClick.Invoke(); } } }