Unity_본캠프

[내일배움캠프 23일차] Unity팀 프로젝트: 트랩 / 클리어용 아이템

티백고래 2025. 5. 9. 23:54

1. 오늘의 할 일

이번 Unity 팀프로젝트에서 게임 오브젝트를 맡았다.

이번 게임은 FireMan & WaterGirl 형식의 퍼즐게임.

그렇기 때문에 게임오브젝트에 필요한 내용은 다음과 같다.

 

1. 함정 - 특정 캐릭터가, 본인에게만 해당하는 함정에 부딪히면 다시 초기 지점으로 강제복귀

2. 유물 - 게임을 클리어하기 위한 요소 중 하나. 각 스테이지의 유물을 전부 모아야 도전과제가 완료된다.

3. 포인트 아이템 - 특정 캐릭터가, 본인에게만 해당하는 아이템에 부딪히면 점수 획득

 

이 중 현재 완료된 것은 1과 2로 두 가지이다. 하지만 실제로 필요한 아이템은 한 두개가 아니므로 풀어지지 않기.

2. 제작 시작🛠️

1. 함정

함정은 플레이어블 캐릭터의 Tag를 비교하도록 만들었다. (Dog/Cat)

개는 개의 함정에 부딪히면, 고양이는 고양이의 함정에 부딪히면 작동한다. 

 

일단 어떻게 기능하는지 영상을 보도록 하자 (각 오브젝트의 테스트용 맵이다)

 

보면 고양이는 볼풀은 편하게 지나가지만 캣닢(풀)에 닿으면 다시 초기자리로 돌아가는 것을 확인할 수 있다.

마찬가지로 개 역시, 캣닢(풀)에서는 편하게 지나가지만, 볼풀에 닿으면 초기자리로 돌아가버린다.

 

의외로 구현은 그렇게 어렵지 않다.

 

 [Header("비교할 태그")] public string compareTag;
 public GameObject Dog;
 public GameObject Cat;
 private Vector3 initialDogPosition; //초기 개의 위치
 private Vector3 initialCatPosition; //초기 고양이의 위치

 private void Start()
 {
     //각 플레이어의 포지션 초기값 세팅
     initialDogPosition = Dog.transform.position;
     initialCatPosition = Cat.transform.position;        
 }


 public string GetTargetTagName()
 {
     return compareTag;
 }

 private void OnTriggerEnter2D(Collider2D collision)
 {
     GetTargetTagName();
     if (collision.CompareTag(compareTag))
     {
         //오브젝트의 TargetName과 부딪힌 Player의 태그비교
         //개가 부딪혔다면 개, 고양이가 부딪혔다면 고양이가 초기위치로 감
         //이를 활용하면, 이후 추락해서 사라져버리거나 원위치 시킬 수 없는 오브젝트도 원래 자리에 옮길 수 있음
         if(compareTag == "Dog")
         {
             Dog.transform.position = initialDogPosition;
         }
         else if(compareTag == "Cat")
         {
             Cat.transform.position = initialCatPosition;
         }
     }
 }

게임이 시작했을 때, 각 플레이어(개/고양이)의 씬 내의 위치를 저장한다.

=>이후 게임 매니저 등에서, 새로운 씬(게임)이 시작할 때마다 새로 재정의 하도록 해야한다.

그리고 함정오브젝트를 깔아둔 타일맵에 Trap.cs를 각각 분리해서 넣어준다. (사유: 비교할 태그가 다르기 때문이다)

그러면 CompareTag(public string) 에 해당 함정에 반응할 캐릭터의 태그를 지정해준다.

(개에게만 반응할 거라면 Dog, 고양이에게만 반응할 거라면 Cat)

캐릭터에게도 Tag가 잘 붙어있는 지 확인하고, Trigger도 잘 켜주면 된다.

 

(가만히 생각해보니까 이거. 굳이 Dog랑 Cat 할 필요없이 GameObject를 Player로 하면 된다....굳이 중복되는 내용을 쓸 필요가 없다. compareTag에서 이미 동일한 string이라는 게 증명된 것이다!)

 

2. 유물

유물은 고양이나 개, 둘 중 하나가 붙으면 Destroy 하도록 만들었다.

하지만, 이 '유물'은 도전과제에 쓸 오브젝트. 그냥 파괴되기만 하면 안된다.

각 오브젝트를 획득하고, 그에 따라 도전과제 클리어가 되도록 만드는 게 목적이다.

 

그렇기에, 각 오브젝트에 ID를 할당하기로 했다. (이 스크립트 하나만 있으면 DataManager, ObjManager를 통해 0부터 9까지 모든 오브젝트를 활용해줄 수 있다.)

    [SerializeField] public int LegacyID;

    void GetGift()
    {
        //획득한 유물의 ID(번호)가 DataManager의 AquiredLegacy에 없을 경우
        if (!DataManager.AquiredLegacy.Contains(LegacyID))
        {
            //LegacyID를 DataManager의 AquiredLegacy에 추가, 유물이 리스트에 잘 들어갔는지 확인.
            DataManager.AquiredLegacy.Add(LegacyID);
            Debug.Log($"유물획득: {ObjManager.LegacyList[LegacyID].ToString()}");
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        //충돌체가 개나 고양이인지 확인(둘은 플레이어)
        if (collision.CompareTag("Dog") || collision.CompareTag("Cat"))
        {
            GetGift();
            Destroy(gameObject); //유물을 등록하고 오브젝트는 제거
        }
    }

각 유물들은 고유의 ID를 가진다. (0은 야구공(튜토리얼용 유물), 1부터는 각 맵에 맞는 오브젝트가 배치된다.)

: ID는 인스펙터 창에서 지정


그럼 DataManager에서 HashSet을 이용해 중복을 제거하며 획득한 유물의 Key값을 저장한다.

그리고 이 Key값은 ObjManager의 Dictionary에 저장된 Key값과 value(string)을 배정받게 된다.

 

3. 내일 할 일

이렇게 오늘 작업한 내용들의 정리가 끝이 났다.

써놓고 보니 코드가 짧아서 이것밖에 못했나, 싶을 수도 있곘지만... 그 안에는 코드를 집어넣고 정상작동 시키기 위한 고뇌가 있었음을 잊지 말도록 하자.

 

내일은 주말! 내일은 쉬면서 간단히 다음 작업을 진행할 예정이다.

이미 벌써 어느정도 게임의 형태를 갖춘 것이 기쁘다.