chyam

[unity] - 인벤토리 아이템 클릭 시 설명창 띄우기 본문

unity

[unity] - 인벤토리 아이템 클릭 시 설명창 띄우기

chyam_eun 2025. 3. 18. 20:53

인벤토리 창에서 아이템을 클릭하고, 해당 슬롯 안에 마우스가 머물러있을때만 설명창이 나타나도록 해주었습니다!

 

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

public Image followMouseImage;

private void Update()
{
    followMouseImage.transform.position = Input.mousePosition+new Vector3(0,100,0); // 마우스 이동하는 곳으로 따라다님
    TextMeshProUGUI explainText = followMouseImage.transform.GetChild(0).GetComponent<TextMeshProUGUI>(); // 설명적는곳
    
    GameObject obj = GetObjectUnderMouse();
    if (obj == null) // 슬롯에서 벗어났으면 설명창 닫기
    { 
        followMouseImage.gameObject.SetActive(false);
    }
    ...
    
    if (Input.GetMouseButtonDown(0)) // 좌클릭 누를때
    {
        curSlot = GetObjectUnderMouse(); //현재 슬롯을 curSlot으로 저장
    }
    else if (Input.GetMouseButton(0))
    { // 누르고 있을때
        if (curSlot && curSlot.GetComponent<Slots>().slotsItem) // 현재 슬롯이 있고, 슬롯안에 아이템이 있을 때
        {
            followMouseImage.gameObject.SetActive(true); // 아이템 설명 이미지+텍스트 보이도록..
            if (obj != null && obj.GetComponent<Slots>() != null && obj.GetComponent<Slots>().slotsItem != null)
            {
                explainText.text = obj.GetComponent<Slots>().slotsItem.GetComponent<Item1>().itemExplain;
            }
            else
            {
                followMouseImage.gameObject.SetActive(false);
                //explainText.text = ""; // 또는 다른 기본 텍스트를 넣어줄 수 있습니다.
            }

            if (GetObjectUnderMouse() == null) // 슬롯에서 벗어났으면 설명창 닫기
            {
                followMouseImage.gameObject.SetActive(false);
            }
        }
        else
        {
            followMouseImage.gameObject.SetActive(false);
        }
    }
    else if (Input.GetMouseButtonUp(0)) // 좌클릭을 떼면 
    {
        if (curSlot && curSlot.GetComponent<Slots>().slotsItem) // 현재 슬롯이 있고, 슬롯안에 아이템이 있을 때
        {
            curSlotsItem = curSlot.GetComponent<Slots>().slotsItem; // 현재 슬롯의 아이템
            GameObject newObj = GetObjectUnderMouse(); // 뗀 곳의 슬롯
            if (newObj && newObj != curSlot) // 새로운 슬롯이 있고, 현재와 다를떄
            {
                if (newObj.GetComponent<Slots>().slotsItem) // 새로운 슬롯의 아이템이 있으면 
                {
                    Item1 objectsItem = newObj.GetComponent<Slots>().slotsItem; // 새로운 슬롯의 아이템
                    if (objectsItem.itemID == curSlotsItem.itemID && objectsItem.amountInStack!=objectsItem.maxStackSize) // 새로운 슬롯의 아이템과 현재 슬롯의 아이템이 같고 새로운 슬롯의 아이템의 갯수가 최대가 아니면
                    {
                        curSlotsItem.transform.parent = null; // 현재 슬롯 아이템을 슬롯(부모)에서 제거함
                        inv.AddItem(curSlotsItem, objectsItem); // 현재 슬롯 아이템을 새로운 슬롯의 아이템에 추가함 
                    }
                    else // 아이템이 다르거나 최대이면 
                    {
                        objectsItem.transform.parent = curSlot.transform; // 새로운 슬롯의 아이템을 현재(원래의) 슬롯의 위치로
                        curSlotsItem.transform.parent = newObj.transform; // 현재 슬롯의 아이템을 새로운 슬롯의 위치로
                    }
                }
                else // 새로운 슬롯이 비어있다면
                {
                    curSlotsItem.transform.parent = newObj.transform; // 현재 슬롯의 아이템을 새로운 슬롯의 위치로
                }
            }
        }
        else // 현재 슬롯이 없거나 슬롯안에 아이템이 없을때
        {
            followMouseImage.gameObject.SetActive(false);
        }
    }
}

private GameObject GetObjectUnderMouse() // 마우스 아래에있는게 슬롯이면 해당 슬롯 반환, 아니면  null
{
    GraphicRaycaster rayCaster = GetComponent<GraphicRaycaster>(); // 캔버스에 충돌한게 있는지? ( UI에서 마우스 클릭이 감지된 오브젝트 찾을수있음 )
    PointerEventData eventData = new(EventSystem.current); // Pointer이벤트 데이터 생성

    eventData.position = Input.mousePosition; //현재 마우스 포인터 위치 저장

    List<RaycastResult> results = new List<RaycastResult>(); 

    rayCaster.Raycast(eventData, results); // 충돌한 모든 UI요소를 results에 저장

    foreach(RaycastResult i in results)
    {
        if (i.gameObject.GetComponent<Slots>()) // 충돌한 오브젝트가 슬롯인가?
        {
            return i.gameObject; // 해당 오브젝트 반환
        }
    }
    return null; // 슬롯이 없으면 null
}

 

 

먼저 캔버스 안에 followMouseImage(Image)와 설명부분(text)을 넣어줍니다.

그리고 아이템에 아이템 설명도 추가해줍니다.

 

 

 

followMouseImage.transform.position = Input.mousePosition+new Vector3(0,100,0); // 마우스 이동하는 곳으로 따라다님
TextMeshProUGUI explainText = followMouseImage.transform.GetChild(0).GetComponent<TextMeshProUGUI>(); // 설명적는곳

 

대강 아래 그림과 같이 만들어 주고싶어서

followMouseImage의 위치를 마우스의 위치에서 100만큼 위로 올라간곳으로 해주었습니다. 

그리고 이 이미지 안에 들어갈 설명 텍스트를 선언해주었습니다.

 

GameObject obj = GetObjectUnderMouse();
if (obj == null) // 슬롯에서 벗어났으면 설명창 닫기
{ 
    followMouseImage.gameObject.SetActive(false);
}

 

obj에서 GetObjectUnderMouse의 값을 저장해주었습니다.

slot에서 벗어났다면 설명창을 닫아줍니다. 

 

private GameObject GetObjectUnderMouse() // 마우스 아래에있는게 슬롯이면 해당 슬롯 반환, 아니면  null
{
    GraphicRaycaster rayCaster = GetComponent<GraphicRaycaster>(); // 캔버스에 충돌한게 있는지? ( UI에서 마우스 클릭이 감지된 오브젝트 찾을수있음 )
    PointerEventData eventData = new(EventSystem.current); // Pointer이벤트 데이터 생성

    eventData.position = Input.mousePosition; //현재 마우스 포인터 위치 저장

    List<RaycastResult> results = new List<RaycastResult>(); 

    rayCaster.Raycast(eventData, results); // 충돌한 모든 UI요소를 results에 저장

    foreach(RaycastResult i in results)
    {
        if (i.gameObject.GetComponent<Slots>()) // 충돌한 오브젝트가 슬롯인가?
        {
            return i.gameObject; // 해당 오브젝트 반환
        }
    }
    return null; // 슬롯이 없으면 null
}

이 메서드는 현재 마우스가 위치해있는 곳이 slot이면 해당 slot을 반환하고, 아니면 null을 반환해줍니다. 

 

    if (Input.GetMouseButtonDown(0)) // 좌클릭 누를때
    {
        curSlot = GetObjectUnderMouse(); //현재 슬롯을 curSlot으로 저장
    }

좌클릭을 눌렀을 때는 현재 슬롯을 curSlot으로 저장해줍니다.

 

else if (Input.GetMouseButton(0))
    { // 누르고 있을때
        if (curSlot && curSlot.GetComponent<Slots>().slotsItem) // 현재 슬롯이 있고, 슬롯안에 아이템이 있을 때
        {
            followMouseImage.gameObject.SetActive(true); // 아이템 설명 이미지+텍스트 보이도록..
            if (obj != null && obj.GetComponent<Slots>() != null && obj.GetComponent<Slots>().slotsItem != null)
            {
                explainText.text = obj.GetComponent<Slots>().slotsItem.GetComponent<Item1>().itemExplain;
            }
            else
            {
                followMouseImage.gameObject.SetActive(false);
            }

            if (GetObjectUnderMouse() == null) // 슬롯에서 벗어났으면 설명창 닫기
            {
                followMouseImage.gameObject.SetActive(false);
            }
        }
        else
        {
            followMouseImage.gameObject.SetActive(false);
        }
    }

좌클릭을 누르고 있을 때는 현재 슬롯이 있고, 슬롯안에 아이템이 있다면 해당 아이템의 설명이 보이게 해줍니다. 만약 해당 슬롯이 null이거나 아이템이 없거나 slots 컴포넌트가 없으면 설명창이 보이지 않게 해줍니다. 

이 조건을 해줘야 아이템을 끌고 빈 슬롯에 놔둘때 null오류가 뜨지 않습니다.

 

 

 else if (Input.GetMouseButtonUp(0)) // 좌클릭을 떼면 
    {
        if (curSlot && curSlot.GetComponent<Slots>().slotsItem) // 현재 슬롯이 있고, 슬롯안에 아이템이 있을 때
        {
            curSlotsItem = curSlot.GetComponent<Slots>().slotsItem; // 현재 슬롯의 아이템
            GameObject newObj = GetObjectUnderMouse(); // 뗀 곳의 슬롯
            if (newObj && newObj != curSlot) // 새로운 슬롯이 있고, 현재와 다를떄
            {
                if (newObj.GetComponent<Slots>().slotsItem) // 새로운 슬롯의 아이템이 있으면 
                {
                    Item1 objectsItem = newObj.GetComponent<Slots>().slotsItem; // 새로운 슬롯의 아이템
                    if (objectsItem.itemID == curSlotsItem.itemID && objectsItem.amountInStack!=objectsItem.maxStackSize) // 새로운 슬롯의 아이템과 현재 슬롯의 아이템이 같고 새로운 슬롯의 아이템의 갯수가 최대가 아니면
                    {
                        curSlotsItem.transform.parent = null; // 현재 슬롯 아이템을 슬롯(부모)에서 제거함
                        inv.AddItem(curSlotsItem, objectsItem); // 현재 슬롯 아이템을 새로운 슬롯의 아이템에 추가함 
                    }
                    else // 아이템이 다르거나 최대이면 
                    {
                        objectsItem.transform.parent = curSlot.transform; // 새로운 슬롯의 아이템을 현재(원래의) 슬롯의 위치로
                        curSlotsItem.transform.parent = newObj.transform; // 현재 슬롯의 아이템을 새로운 슬롯의 위치로
                    }
                }
                else // 새로운 슬롯이 비어있다면
                {
                    curSlotsItem.transform.parent = newObj.transform; // 현재 슬롯의 아이템을 새로운 슬롯의 위치로
                }
            }
        }
        else // 현재 슬롯이 없거나 슬롯안에 아이템이 없을때
        {
            followMouseImage.gameObject.SetActive(false);
        }
    }

 

좌클릭을 떼면 끌어온 아이템을 새로운 슬롯에 저장할수있습니다