20240108_맵의 상호작용 물체 만들기

2024. 1. 8. 23:53IT/TIL

오늘의 TIL은 맵 상에서 플레이어와 상호작용하는 물체를 만드는 내용이다.

 

 

위의 이미지처럼, 표지판에 플레이어가 닿으면(플레이어가 오브젝트 collider에 닿으면) 특정 문구가 나오는 기능을 구현했다.

 

오브젝트를 구성하는 것은 아래의 이미지처럼 단순한데,

 

 

플레이어와 상호작용하는 게임 오브젝트에는 Box Collider 2D(Is Trigger 체크)와 아래의 스크립트를 추가하면 되는데,

 

특정 오브젝트를 판단하기 위해 Tag를 사용하였다.

 

실제로 사용한 코드는 아래와 같은데,

더보기
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;

public class InteractText : MonoBehaviour
{
    public GameObject textObject;
    private TextMeshProUGUI TMPText;


    private void Start()
    {
        TMPText = textObject.GetComponentInChildren<TextMeshProUGUI>();
        textObject.SetActive(false);
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            if (gameObject.CompareTag("Shop"))
            {
                TMPText.text = "Press 'E' to use the shop";
            }
            else if (gameObject.CompareTag("Well"))
            {
                TMPText.text = "Press 'E' to use the Well" + "\r\n" + "Well can help your Health";
            }
            else if (gameObject.CompareTag("FirstTable"))
            {
                TMPText.text = "Jump to hole, You can start your Adventure";
            }
            else if (gameObject.CompareTag("Table"))
            {
                TMPText.text = "Go Right side" + "\r\n" + "You can proceed to the next level";
            }
            else if (gameObject.CompareTag("RightTable"))
            {
                TMPText.text = "You find right way" + "\r\n" + "Keep Going!!";
            }
            else if (gameObject.CompareTag("WrongTable"))
            {
                TMPText.text = "You are reached the Wrong direction" + "\r\n" + "Find another way";
            }
            else if (gameObject.CompareTag("14Table"))
            {
                TMPText.text = "Hurry Up" + "\r\n" + "Someone chasing you!";
            }
            else if (gameObject.CompareTag("15Table"))
            {
                TMPText.text = "This is the final stage" + "\r\n" + "Can you Defeat him?";
            }

            textObject.SetActive(true);
        }
    }

    private void OnTriggerStay2D(Collider2D collision)
    {
        if (gameObject.CompareTag("Shop"))
        {
            if (Input.GetKey(KeyCode.E))
            {
                textObject.SetActive(false);

                // Todo -> 상점 관련 작업
            }
        }
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            textObject.SetActive(false);
        }
    }
}

 

이 코드들을 살펴보면 OnTrigger의 3형제를 사용하였다.

 

public GameObject textObject;
private TextMeshProUGUI TMPText;

private void Start()
{
    TMPText = textObject.GetComponentInChildren<TextMeshProUGUI>();
    textObject.SetActive(false);
}

 

우선 화면에 표시한 textObject를 선언하고, Hierarchy 창에서 드래그 앤 드롭으로 넣어준다(사진의 오른쪽 아래 빨간줄).

 

여기서 중요한 점은 TMPtext를 바로 넣는 것이 아니고, 그 위에 있는 Canvas를 넣어준 것이다.

 

이후에 시작 시에 TMPText를 해당하는 Canvas에서 찾아오게 만든 후에,

 

이 TMPText를 갖고 있는 canvas를 보이지 않게 설정하였다.

 

 

이후에 OnTrigger 3형제 중에서 가장 중요하고 복잡한 OnTriggerEnter2D를 살펴보면,

private void OnTriggerEnter2D(Collider2D collision)
{
    if (collision.CompareTag("Player"))
    {
        if (gameObject.CompareTag("Shop"))
        {
            TMPText.text = "Press 'E' to use the shop";
        }
        else if (gameObject.CompareTag("Well"))
        {
            TMPText.text = "Press 'E' to use the Well" + "\r\n" + "Well can help your Health";
        }
        else if (gameObject.CompareTag("FirstTable"))
        {
            TMPText.text = "Jump to hole, You can start your Adventure";
        }
        else if (gameObject.CompareTag("Table"))
        {
            TMPText.text = "Go Right side" + "\r\n" + "You can proceed to the next level";
        }
        else if (gameObject.CompareTag("RightTable"))
        {
            TMPText.text = "You find right way" + "\r\n" + "Keep Going!!";
        }
        else if (gameObject.CompareTag("WrongTable"))
        {
            TMPText.text = "You are reached the Wrong direction" + "\r\n" + "Find another way";
        }
        else if (gameObject.CompareTag("14Table"))
        {
            TMPText.text = "Hurry Up" + "\r\n" + "Someone chasing you!";
        }
        else if (gameObject.CompareTag("15Table"))
        {
            TMPText.text = "This is the final stage" + "\r\n" + "Can you Defeat him?";
        }

        textObject.SetActive(true);
    }
}

 

해당하는 오브젝트와 collision되는 Tag가 Player인지 확인한 후에 (적인 경우에는 작동되지 않게)

 

이후에 이 오브젝트가 어떤 Tag를 갖고 있는지에 따라 나타나는 글씨를 설정하였다.

 

이 if 안의 if와 else if 문은 모두 반복되는 것들이라 자세히는 설명하지 않지만,

 

TMPText.text에서 2줄로 나눠서 글을 표시하고 싶을 때에는

 

"Text 1" + "\r\n" + "Text 2"를 이용하면 텍스트의 줄을 나눠서 표시할 수 있다.

 

 

다음으로 OnTriggerStay2D를 살펴보면

 

private void OnTriggerStay2D(Collider2D collision)
{
    if (gameObject.CompareTag("Shop"))
    {
        if (Input.GetKey(KeyCode.E))
        {
            textObject.SetActive(false);

            // Todo -> 상점 관련 작업
        }
    }
}

 

OnTriggerStay2D의 경우에는 해당 오브젝트와 닿아있는 경우,

 

다시 말해서 오브젝트 안에 플레이어가 존재하는 경우에 어떠한 행동을 취할 수 있는 함수로

 

여기서 구현하고 싶었던 것은 상점인 경우에 E 키를 눌러서 상점으로 진입하는 것이었다.

 

(Enter2D와 다르게 플레이어인지 확인하지 않는 것은 상점은 마을에만 있기 때문에

 이 상호작용을 하는 경우에는 플레이어만 상호작용하게 만들기 때문이다.

 만약 다른 상호작용이 가능한 물체가 있다면 위와 같이 if (collision.CompareTag("Player")를 써야한다)

 

이 경우에는 해당하는 글씨를 지운 후에 상점을 표시하는 등의 작업을 진행하려고 하였으나 상점은 구현하지 못했다.

 

 

마지막으로 OnTriggerExit2D를 살펴보면

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Player"))
        {
            textObject.SetActive(false);
        }
    }

 

플레이어가 collision을 벗어나는 순간 text를 표시하지 않게 만들었다.

 

만약 if 문이 없다면, 몬스터가 오브젝트와 닿았다가 떨어지는 순간 text가 사라지는 오류가 생기게 된다.

 

 

 

오늘은 플레이어가 이동하면서 어떠한 오브젝트에 닿았을 경우에 상호작용하는 내용을 구현했는데,

 

다양한 텍스트를 사용하고 싶어서 Tag를 많이 만든 부작용을 겪었다.

 

이렇게 다양한 표지판을 만드는 경우에 좀 더 깔끔하게 작업할 수 있는 방법을 고민했는데,

 

하나는 이번에 사용한 다양한 Tag를 이용하여 text를 여러 개 만드는 방법과

 

다른 하나는 오브젝트마다 text를 만든 후에, 상호작용하면 해당하는 text를 표시하고 끄는 방법이였다.

 

개인적으로는 이번에 사용한 방법이 좀 더 좋은 것으로 판단되어 사용하였지만,

 

이 보다도 더 좋은 방법이 있을 것으로 생각된다.

 

이 방법을 사용했을 때의 문제점이 Tag를 너무 많이 사용하게 된다는 점과 스크립트에서 너무 많은 텍스트를 사용하게 된다는 점이다

 

이전에 게임을 만들면서 사용했던 방법은 스크립트에 들어가는 텍스트를 다른 텍스트 문서에서 받아오는 방식을 사용했는데,

 

유니티에서도 그렇게 다른 텍스트 문서에서 필요한 텍스트를 받아오는 방식이 있을 것으로 생각된다.

 

이 부분에 대해서도 공부해볼 예정이다.

'IT > TIL' 카테고리의 다른 글

20240110_FSM, BT  (0) 2024.01.10
20240109_C#에서의 순열  (0) 2024.01.09
20240105_함정 만들기  (0) 2024.01.08
20230104_카메라 이동  (0) 2024.01.04
20240103_맵 만들기  (0) 2024.01.04