chyam

[Unity] - UI 버튼 선택/해제 구현 본문

unity

[Unity] - UI 버튼 선택/해제 구현

chyam_eun 2025. 9. 1. 16:35

원래 버튼을 중복 선택 가능하도록 구현해두었었는데,

 

[unity] - 버튼 클릭하여 저장된 정보 불러오기

클릭한 정보(요리 재료)를 저장하여 최종 화면에서 정보에 관한 이미지가 나타나도록 해주었습니다! 먼저, 주문 사항을 체크해주는 UI를 만들어줍니다. check_menu( Panel ) 을 추가해주고 그 안에 내

chyam-eun.tistory.com

 

버튼 선택 하나만 적용되도록 변경하였습니다.

 

 

목표는, 쉐이크와 쿠키 각각 하나 이하로만 선택하도록 하는것입니다. (기본재료인 피클,양배추,머스타드,칠리는 그대로 중복 선택..)

 

새로 ItemCheck라는 스크립트를 만들어서 각 아이템들에게 넣어주었습니다.

 

먼저, 선언한 변수들을 보자면 아래와 같습니다.

private static ItemCheck selectedCookie = null; // 현재 선택된 쿠키 버튼
private static ItemCheck selectedDrink = null;  // 현재 선택된 음료 버튼
private bool isSelect = false; // 자신(버튼)이 선택되었는지
private Image image; // 버튼의 색을 바꾸기 위한 변수

[SerializeField] 
private ReadSpreadSheet sheet; // 스프레드 시트 스크립트

private void Start()
{
    image = GetComponent<Image>();
}

쿠키나 음료를 각 하나이하로만 선택할 수 있기 때문에, 처음에는 각각 null로 초기화해줍니다.

이때 sheet는 꼭 유니티에서 지정해서 넣어줘야합니다.

 

public void select()
{
    string name = gameObject.transform.GetChild(0).name; // 선택된 재료의 이름

    if (name.Contains("cookie")) // 쿠키일 때
    {
        HandleSelection(ref selectedCookie, name);
    }
    else if (name.Contains("drink")) // 쉐이크일 때
    {
        HandleSelection(ref selectedDrink, name);
    }
}

ref는 함수 내부에서 값을 변경해도 원래 변수의 값도 함께 변경되도록 해줍니다. 그러므로 HandleSelection 함수 내부에서 값이 변경되면 밖에 있는 값도 함께 변합니다.

 

쿠키일 때와 쉐이크일 때 각각 하나씩 적용되므로 두가지로 나눠서 체크를 해주었습니다.

 

private void HandleSelection(ref ItemCheck selectedItem, string name)
{
    // 다른 버튼이 선택되어 있으면 해제
    if (selectedItem != null && selectedItem != this)
    {
        selectedItem.Deselect();
    }

    // 현재 버튼 상태 토글
    isSelect = !isSelect;

    if (isSelect)
    {
        selectedItem = this;
    }
    else
    {
        selectedItem = null;
    }

    // 스프레드시트 반영
    sheet.OnIngredientToggled(name, isSelect);

    // 색상 반영
    image.color = isSelect ? new Color32(220, 200, 200, 255)
                           : new Color32(255, 255, 255, 255);
}

만약 다른버튼이 선택되어있다면 그 버튼의 선택을 해제하고, 현재 버튼을 선택하도록 합니다.

또한 자신이 선택되어있다면 버튼의 선택을 해제 하도록합니다. 

그런 뒤, isSelect를 통해 누른 버튼을 알 수 있습니다. 누르면 약간 붉은색으로 표시됩니다.

또한 눌렀을때 그 음식의 비용을 사용하기 위해 스프레드 시트에도 반영해줍니다.

 

private void Deselect() // 선택 해제
{
    if (!isSelect) return;
    isSelect = false;
    image.color = new Color32(255, 255, 255, 255); // 원래 색으로 돌림
    string name = gameObject.transform.GetChild(0).name; 
    sheet.OnIngredientToggled(name, false); // 스프레드시트 반영
}

선택된것을 해제하고, 색도 원래대로 돌려줍니다. 또한 해당 이름의 음식의 비용을 다시 돌려주기 위해 스프레드 시트를 사용해줍니다. 

 

그렇게되면 아래처럼 실행됩니다.

 

 

전체 코드

더보기

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ItemCheck : MonoBehaviour
{
    private static ItemCheck selectedCookie = null; // 현재 선택된 쿠키 버튼
    private static ItemCheck selectedDrink = null;  // 현재 선택된 음료 버튼
    private bool isSelect = false;
    private Image image;

    [SerializeField] 
    private ReadSpreadSheet sheet;

    private void Start()
    {
        image = GetComponent<Image>();
    }

    public void select()
    {
        string name = gameObject.transform.GetChild(0).name; // 선택된 재료의 이름

        if (name.Contains("cookie")) // 쿠키일 때
        {
            HandleSelection(ref selectedCookie, name); // ref는 함수 내부에서 값을 변경해도 원래 변수의 값도 함께 변경되도록 함.
        }
        else if (name.Contains("drink")) // 쉐이크일 때
        {
            HandleSelection(ref selectedDrink, name);
        }
    }
    private void HandleSelection(ref ItemCheck selectedItem, string name)
    {
        // 다른 버튼이 선택되어 있으면 해제
        if (selectedItem != null && selectedItem != this)
        {
            selectedItem.Deselect();
        }

        // 현재 버튼 상태 토글
        isSelect = !isSelect;

        if (isSelect)
        {
            selectedItem = this;
        }
        else
        {
            selectedItem = null;
        }

        // 스프레드시트 반영
        sheet.OnIngredientToggled(name, isSelect);

        // 색상 반영
        image.color = isSelect ? new Color32(220, 200, 200, 255)
                               : new Color32(255, 255, 255, 255);
    }

    private void Deselect() // 선택 해제
    {
        if (!isSelect) return;
        isSelect = false;
        image.color = new Color32(255, 255, 255, 255); // 원래 색으로 돌림
        string name = gameObject.transform.GetChild(0).name; 
        sheet.OnIngredientToggled(name, false); // 스프레드시트 반영
    }
}