2026-03-22 스왑버튼 그룹구현

This commit is contained in:
2026-03-22 18:57:56 +09:00
parent e0116ec98c
commit faf692673d
10 changed files with 182 additions and 53 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7e80643c255c6374380bcd76c229008a
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,108 @@
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
[ExecuteAlways]
[RequireComponent(typeof(Image))]
public class SwapButton : MonoBehaviour, IPointerClickHandler
{
[SerializeField] private SwapButtonGroup _group;
public SwapButtonGroup Group
{
get => _group;
set
{
if (_group != null) _group.UnregisterButton(this);
_group = value;
if (_group != null) _group.RegisterButton(this);
}
}
[Space(10)]
public Image TargetImage;
[Space(10)]
public Sprite TrueSprite;
public UnityEvent TrueEvent = new UnityEvent();
public Sprite FalseSprite;
public UnityEvent FalseEvent = new UnityEvent();
[SerializeField] private bool _trueA_FalseB = true;
public bool TrueA_FalseB
{
get => _trueA_FalseB;
set
{
if (_trueA_FalseB == value) return;
_trueA_FalseB = value;
UpdateVisual(); // 값이 바뀔 때마다 자동으로 실행!
if (_trueA_FalseB && _group != null)
{
_group.OnButtonSelected(this);
}
}
}
private void Awake()
{
TargetImage = GetComponent<Image>();
// 시작할 때 그룹이 설정되어 있다면 등록
if (_group != null) _group.RegisterButton(this);
}
private void Start()
{
UpdateVisual();
}
public void OnPointerClick(PointerEventData eventData)
{
if (_group != null)
{
// 라디오 버튼 모드: 이미 선택된 건 다시 눌러도 무반응
if (_trueA_FalseB) return;
TrueA_FalseB = true; // 나를 True 상태로
TrueEvent?.Invoke();
}
else
{
// 그룹이 없으면 기존처럼 토글
TrueA_FalseB = !TrueA_FalseB;
if (TrueA_FalseB)
TrueEvent?.Invoke();
else
FalseEvent?.Invoke();
}
}
private void OnValidate()
{
UpdateVisual();
if (_trueA_FalseB && _group != null)
{
_group.OnButtonSelected(this);
}
}
public void UpdateVisual()
{
if (TargetImage == null) return;
TargetImage.sprite = _trueA_FalseB ? TrueSprite : FalseSprite;
}
private void OnDestroy()
{
// 오브젝트 삭제 시 그룹에서 해제
if (_group != null) _group.UnregisterButton(this);
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7742f072d8001394ca9c68f41507c667

View File

@@ -0,0 +1,48 @@
using System.Collections.Generic;
using UnityEngine;
[ExecuteAlways]
public class SwapButtonGroup : MonoBehaviour
{
// 현재 이 그룹에 등록된 모든 버튼들
private List<SwapButton> _registeredButtons = new List<SwapButton>();
// 버튼이 활성화되거나 그룹이 할당될 때 호출됨
public void RegisterButton(SwapButton button)
{
if (!_registeredButtons.Contains(button))
{
_registeredButtons.Add(button);
if (button.TrueA_FalseB == true)
{
foreach (SwapButton sb in _registeredButtons)
{
if (sb == button) continue;
sb.TrueA_FalseB = false;
}
}
}
}
// 버튼이 파괴되거나 그룹에서 빠질 때 호출됨
public void UnregisterButton(SwapButton button)
{
if (_registeredButtons.Contains(button))
{
_registeredButtons.Remove(button);
}
}
// 특정 버튼이 선택되었을 때 나머지 버튼들을 모두 B(False)상태로 만듦
public void OnButtonSelected(SwapButton selectedButton)
{
foreach (SwapButton button in _registeredButtons)
{
if (button == selectedButton) continue;
button.TrueA_FalseB = false;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: f7aa52a51f8c48046870a87acf509e27