ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • (26) UI - Item Icon & 턴제 재구현
    Galaxy Ball/1. 멀티플레이 - 대전모드 2024. 5. 3. 16:53

    사실 이전부터 거슬렸던 버그가 하나 있었다

     

    이렇게 아이템 아이콘과 게임속 구체 오브젝트가 겹쳤을때 아이템 클릭판정이 안된다는것

    using UnityEngine;
    
    public class ItemIconDestroy : MonoBehaviour
    {
        public IconAudioPlay iconAudioPlay;
        private Camera mainCamera;
    
        private void Start()
        {
            mainCamera = Camera.main;
        }
    
        private void Update()
        {
            if (Input.GetMouseButtonDown(0))
            {
                Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
                RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction);
                if (hit.collider != null && hit.collider.gameObject == gameObject)
                {
                    string destroyedIconTag = hit.collider.gameObject.tag;
                    GameManager icontag = FindObjectOfType<GameManager>(); // 임시로 적용한 코드입니다.
                    icontag.PrintDestroyedicontag(destroyedIconTag);
                    Debug.Log("아이템 " + destroyedIconTag + " 을 클릭했습니다");
    
                    Destroy(gameObject);
                }
            }
        }
    }

    아니 분명 구체 레이어는 2, 아이템 레이어는 5인데 어째서 클릭이 되질 않는걸까

    근데 또 이게 될때가 있고 안될때가 있다는것이다. 그래서 한번 찾아보니

     

     

    챗gpt에서는 총 3가지 방법을 제시했다.

     

    2번은 사실상 위 코드와 크게 다를거없는 말 같고, 3번은 문장 그대로 추가적인 로직을 짜야했기 때문에

    조금은 생소하게 들리는 'OnMouseDown' 이라는 방법을 사용해보기로 했다

     

    using UnityEngine;
    
    public class ItemIconDestroy : MonoBehaviour
    {
        public IconAudioPlay iconAudioPlay;
    
        private void OnMouseDown()
        {
            string destroyedIconTag = gameObject.tag;
            GameManager icontag = FindObjectOfType<GameManager>(); // 임시로 적용한 코드입니다.
            icontag.PrintDestroyedicontag(destroyedIconTag);
            Debug.Log("아이템 " + destroyedIconTag + " 을 클릭했습니다");
    
            Destroy(gameObject);
        }
    }

     

    정말 특이하게 마우스 클릭임에도 불구하고 Raycast나 카메라를 사용하지 않는다는게 내겐 좀 낯설지만

     

    유니티 함수 - OnMouseDown(), 마우스 클릭 이벤트 함수

    유니티에서 마우스 클릭 이벤트에 의한 OnMouseDown 함수 호출하기1)씬에서 게임오브젝트를 생성한다.2)마우스 클릭 이벤트에의해 함수를 호출하려면 오브젝트는 콜라이더를 가지고있어야한다.3)

    learnandcreate.tistory.com

    OnMouseDown 함수는 말 그대로 마우스를 클릭했을때 이벤트가 실행되는 함수라고 보면 되겠다

     

    ....이렇게 글을 써가다가 실시간으로 클릭이 막힌것을 확인했다

    그럼 이번엔 아이템 아이콘을 이미지가 아닌 UI 버튼으로 만들어보겠다

    사실 처음부터 이렇게 하는게 맞는데 여태 까먹은것도 있다 

     

    ----------------------------------------------------------------------------

     

    그럼 이번엔 모든 아이템 아이콘을 버튼으로 바꿔주겠다

    우선 모든 아이콘 이미지 배경을 제거해주자

     

    버튼 7개를 만들어 각자의 이미지를 넣어주자

     

    모든 버튼의 이름을 변경해준뒤 이름에 알맞는 태그를 걸어준다

     

    크기도 모두 틀에 알맞게 들어가도록 똑같이 통일해준다

     

    using UnityEngine;
    using UnityEngine.UI;
    
    public class ItemUse : MonoBehaviour
    {
        private void Start()
        {
            Button button = GetComponent<Button>();
            button.onClick.AddListener(() =>
            {
                string destroyedIconTag = gameObject.tag;
                GameManager icontag = FindObjectOfType<GameManager>(); // 임시로 적용한 코드입니다.
                icontag.PrintDestroyedicontag(destroyedIconTag);
                Debug.Log("아이템 " + destroyedIconTag + " 을 클릭했습니다");
                Destroy(gameObject);
            });
        }
    }

     

    이제 이 아이템들에게 들어갈 스크립트를 제작해주자. 이름은 'ItemUse'

    버튼을 클릭하면 해당 버튼의 태그를 GameManager안에 있는 PrintDestroyicontag 메서드에 넘겨주는것까지 똑같다

     

    그전 코드와 다른점이 있다면 이미지 클릭이 아닌 버튼 클릭이라는것

     

    모든 프리팹에 스크립트를 부착해주자. 당연한 얘기지만 버튼이니 Circle Collider 같은건 필요없다

     

    이제 오브젝트가 겹쳐있던말던 클릭이 잘되는것을 확인할 수 있다

     

    아직 끝이 아니다. 이제 저 아이콘들이 아이템을 먹을때마다 양쪽인벤에 나타나야 한다

     

    두 종류로 나눠준다. P1Slot은 검정 사각틀, P1ItemSpawn은 틀 가운데 보이는 빈 오브젝트. 즉 아이템이 생성될 위치이다

     

    P1Slot은 단순 틀 개념이니 아무것도 필요없지만

    직접적인 아이템 스폰을 맡을 P1ItemSpawn에는 전에 짜둔 ShowP1ItemIcon 스크립트를 부착해주자

     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    //획득한 아이템을 아이템 인벤에 저장하는 스크립트
    
    public class ShowP1ItemIcon : MonoBehaviour
    {
        public GameObject[] P1IconPlaces;
        public GameObject[] P1Icon;
        public AudioSource fullItemAudio;
    
        public void PrintDestroyedObjectTag(string objecttag)
        {
            GameObject nextIcon = null;
    
            switch (objecttag)
            {
                case "Item_BlackHole": nextIcon = P1Icon[0]; break;
                case "Item_Durability": nextIcon = P1Icon[1];break;
                case "Item_Fasten":nextIcon = P1Icon[2];break;
                case "Item_Force":nextIcon = P1Icon[3];break;
                case "Item_Invincible":nextIcon = P1Icon[4];break;
                case "Item_Random_number":nextIcon = P1Icon[5];break;
                case "Item_Reduction":nextIcon = P1Icon[6];break;
            }
            if (nextIcon != null)
            {
                foreach (GameObject place in P1IconPlaces)
                {
                    if (place.transform.childCount == 0)
                    {
                        Instantiate(nextIcon, place.transform.position, Quaternion.identity, place.transform);
                        return;
                    }
                }
                fullItemAudio = GetComponent<AudioSource>();
                fullItemAudio.Play();
            }
        }
    }

    아이템을 얻는순간 얻은 아이템의 태그를 이 ShowP1ItemIcon 스크립트에 넘겨주고

    이 스크립트에서는 받은 태그를 가지고 생성할 아이템 아이콘을 결정한뒤 생성해준다

    부착했다면 배열에 각각 올바른 숫자와 오브젝트들을 부착해주자

     

     

    최종적으로 잘 작동하는것을 확인할 수 있다. 전에 만들어두었던 이미지들은 전부 제거해버리자

Designed by Tistory.