chyam

[unity 3d] - 인벤토리 슬롯을 클릭할 때 색상을 변경하기 본문

unity

[unity 3d] - 인벤토리 슬롯을 클릭할 때 색상을 변경하기

chyam_eun 2025. 3. 7. 19:19

<구현 목표>

인벤토리 슬롯을 누르면 색깔이 달라지면서 현재 슬롯임을 알 수 있도록 하기 + 다른 슬롯을 누르면 원래 색깔로 돌아가도록 하기!

 

Inventory 코드에서 수정한 내용은 아래와 같습니다.

public static Inventory Instance;

void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
        }
        ...
        slotText = new TextMeshProUGUI[9];

        for(int i=1; i < 10; i++)
        {
            GameObject textObj = GameObject.Find("num" + i);

            if (textObj != null)
            {
                slotText[i-1] = textObj.GetComponent<TextMeshProUGUI>();
            }
        }
        ...
    }

 

먼저, Instance를 선언해주었는데, 이것은 한 개의 객체를 여러 군데에서 사용하기 위한 방법입니다. 다른 스크립트에서 Inventory 안에 있는 변수나 함수들을 자유롭게 사용할 수 있습니다.

public static Inventory Instance; //인스턴스 선언
void Awake()
{
    if (Instance == null)
    {
        Instance = this; // 현재의 객체를 인스턴스로 지정
    }
   	...
}

 

그리고 원래 slotText를 직접 넣었었는데, 코드로 넣는것으로 수정해주었습니다.

GameObject.Find("")를 사용하면 괄호 안에 있는 이름을 가진 오브젝트를 참조할 수 있습니다.

동일한 이름이 여러개라면 먼저 검색된 오브젝트를 참조하고, 없다면 null을 반환합니다.

 

각각의 이름이 num1, num2 ... 이라서 "num"+(i+1) 로 찾아주었습니다.

오브젝트가 있다면 그것의 텍스트 부분을 slotText에 저장해주었습니다.

slotText = new TextMeshProUGUI[9];

for(int i=0; i < 9; i++)
{
    GameObject textObj = GameObject.Find("num" + (i+1));

    if (textObj != null)
    {
        slotText[i] = textObj.GetComponent<TextMeshProUGUI>();
    }
}

 

 

UIEvent 전체코드는 아래와 같습니다.

UI에 클릭 관련 인터페이스를 사용하기 위해서는 MonoBehaviour 옆에 IPointerClickHandler을 추가해주어야 합니다!

 

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

public class UIEvent : MonoBehaviour, IPointerClickHandler
{
    GameObject prevObject;
    GameObject clickedObject;
    TextMeshProUGUI[] slotText;


    private void Start()
    {
        slotText = Inventory.Instance.slotText;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (prevObject != null)
        {
            int num = int.Parse(prevObject.name.Substring(8, 1));
            print(num);


            if (slotText[num-1].gameObject.GetComponent<TextMeshProUGUI>().text != "0")
            {
                prevObject.GetComponent<Image>().color = new Color(255, 255, 255, 1); // 아이템이있다면 ..
            }
            else
            {
                prevObject.GetComponent<Image>().color = new Color(255, 255, 255, 0); // 아이템이없다면 ..
            }
            

        }

        clickedObject = eventData.pointerCurrentRaycast.gameObject;
        Debug.Log(clickedObject.name);
        if (clickedObject.name.Substring(0, 8) == "SlotItem")
        {
            
            clickedObject.GetComponent<Image>().color = new Color(0, 20, 20, 0.07f); // 밝게해줌
            prevObject = clickedObject;
        }

        
    }
}

 

먼저 변수들은 아래와 같습니다. 

인스턴스를 통해 바로 Inventory 스크립트의 slotText에 접근할 수 있습니다.

GameObject prevObject; // 이전에 클릭한 오브젝트
GameObject clickedObject; // 현재 클릭한 오브젝트
TextMeshProUGUI[] slotText; // 슬롯 텍스트


private void Start()
{
    slotText = Inventory.Instance.slotText; // 인스턴스를 통해 slotText 저장해주기
}

 

그다음은 OnPointerClick함수로 UI 클릭 시 실행되는 함수입니다!

 

clickedObject에 현재 클릭된 오브젝트를 저장해주고, 이것의 이름이 SlotItem.. 일때만 색깔을 변경해준 뒤 prevObject에 저장해줍니다.

 

그리고 다른 슬롯을 클릭했을때, 이전에 클릭된 슬롯은 원래대로 돌아가야 하므로 prevObject에 저장된 이름의 마지막에 있던 숫자를 통해 슬롯에 접근해줍니다.

만약 슬롯에 아이템이 들어있다면( 숫자가 0이 아니라면 ) 투명도를 1로 해주고, 들어있지 않다면 0으로 해줍니다

public void OnPointerClick(PointerEventData eventData)
    {
        if (prevObject != null)
        {
            int num = int.Parse(prevObject.name.Substring(8, 1));

            if (slotText[num-1].gameObject.GetComponent<TextMeshProUGUI>().text != "0")
            {
                prevObject.GetComponent<Image>().color = new Color(1, 1, 1, 1); // 아이템이있다면 ..
            }
            else
            {
                prevObject.GetComponent<Image>().color = new Color(1, 1, 1, 0); // 아이템이없다면 ..
            }
            

        }

        clickedObject = eventData.pointerCurrentRaycast.gameObject;
        if (clickedObject!=null && clickedObject.name.Substring(0, 8) == "SlotItem")
        {
            clickedObject.GetComponent<Image>().color = new Color(0, 0.08f,  0.08f, 0.07f); // 밝게해줌
            prevObject = clickedObject;
        }

    }