카테고리 없음

2025_04_01 TIL

chajungto0211 2025. 4. 1. 23:26
이 글은 평범한 취준생이 평범하게 자신이 당일 배운것들과 느낀점들을 쓰기 때문에 정보가 정확하지 않을 수 있습니다.

오늘은 만우절이다. 딱히 만우절에 거짓말과 관련된 것들은 즐기지 못했지만, 1월 말부터 부트캠프에 참여해 벌써 4월 초까지 온 시간들이 거짓말처럼 느껴지긴 한다. 이런 거짓말 같은 시간들은 한번 더 보내야 하기에, 마음을 다 잡고 오늘의 TIL을 한번 써봐야겠다.

 

1.  맵의 방 인터벌 수정

오늘 서로 맡은 기능들을 합치고 확인할 때, 다른 방에 있는 몬스터가 갑자기 범위 내로 잡혀서 바로 밑 방에 있는 플레이어를 공격해왔다. 그래서 원래는 작다고 생각되었던 interval = 3의 값을 30으로 대폭 늘려 수정하였다.

interval = 30;

 

interval == 3;

확실하게 방과 방 사이의 간격을 늘려서 다른 방의 몬스터의 감지 범위에 잡히지 않도록 하였다.

 

2. 미니 맵 구현

원래는 만들 생각은 없었지만, 생각보다 나의 진도를 일찍 끝내버려서 무언가를 더 만들어볼까? 라고 생각해서 나온게 미니맵이다. 일단 처음 생각했던 건, 맵의 전부를 일반 네모로 보여주고, 엘리트 방이나 보스방 같은 특별한 방은 다른 색으로 보여주게끔 나타내고 싶었다. 

하지만, 우리 팀이 만드는 게임 특성상 앞에 뭐가 있는지 모르는게 재미를 주기 때문에 가는 길을 표시하는 방법으로 만드는게 좋을것 같아, 표시 방법을 바꾸었다.

그리고 플레이어의 현재 위치도 알려주면 좋을 것 같아서, 길 표시와는 다른 Sprite를 만들어서 플레이어가 존재하는 방에만 뜨도록 하게 하였다. 밑은 해당 코드이다.

  • Room.cs의 일부
    //방안에 플레이어가 있으면 표시해주는 함수
    public void PaintCurrentPos()
    {
        if (!currentPlayerPosSquare.activeSelf)
        {
            currentPlayerPosSquare.SetActive(true);
        }
    }

    //방안에 플레이어가 없으면 지워주는 함수
    public void EraseCurrentPos()
    {
        if (currentPlayerPosSquare.activeSelf)
        {
            currentPlayerPosSquare.SetActive(false);
        }
    }
  • MapCreator.cs의 일부
    //미니맵에 현재 위치 표시
    public void ShowPlayerPosition()
    {
        roomMap[currentRoomNum].PaintPath();
        roomMap[currentRoomNum].PaintCurrentPos();
    }

    //미니맵에 현재 위치 지우기
    public void ErasePlayerPosition()
    {
        roomMap[currentRoomNum].EraseCurrentPos();
    }

Room의 코드들을 MapCreator에서 함수로 모아준 뒤 사용해야 할 곳에 적절히 배치해준다.

  • Room.cs
using System;
using System.Collections.Generic;
using UnityEngine;

public enum Direction
{
    Up, Down, Left, Right
}

public class Room : MonoBehaviour
{
    [Header("방의 한변의 길이")]
    public int roomLength = 30;

    [Header("방의 입구들 => 상 하 좌 우 순서")]
    public List<GameObject> roomEnterance;

    [Header("방의 입구들 봉쇄벽 => 상 하 좌 우 순서")]
    public List<GameObject> roomBlock;

    [Header("방의 스폰포인트")]
    public List<Transform> spawnPoint;

    [Header("방의 몬스터 리스트")]
    [SerializeField]
    public List<GameObject> monsterList;

    [Header("미니맵에 방 표시")]
    [SerializeField]
    public GameObject miniMapSquare;

    [Header("미니맵에 플레이어 존재 여부 표시")]
    [SerializeField]
    public GameObject currentPlayerPosSquare;

    [Header("방의 클리어 여부")]       //몬스터가 다 없어진 후에 true를 반환해주어야 함
    public bool isCleared = false;

    private void Awake()
    {
        //몬스터가 죽었을때의 이벤트 구독 예정
        MonsterBase.OnMonsterDied += CheckClear;
        currentPlayerPosSquare.SetActive(false);
        miniMapSquare.SetActive(false);
    }

    //방 생성시 입구 관리
    public void ControlEnterance(Direction dir)
    {
        switch(dir)
        {
            case Direction.Up:
                roomEnterance[0].SetActive(false);
                roomBlock[0].SetActive(true);
                break;
            case Direction.Down:
                roomEnterance[1].SetActive(false);
                roomBlock[1].SetActive(true);
                break;
            case Direction.Left:
                roomEnterance[2].SetActive(false);
                roomBlock[2].SetActive(true);
                break;
            case Direction.Right:
                roomEnterance[3].SetActive(false);
                roomBlock[3].SetActive(true);
                break;
            default: break;
        }

        //조건을 달성하기 전 다른 방으로 이동 못하게 막기
        CloseEnterance();
    }

    //입구 초기화
    public void InitailEnterance()
    {
        foreach(GameObject enterance in roomEnterance)
        {
            enterance.SetActive(true);
        }
        foreach (GameObject block in roomBlock)
        {
            block.SetActive(false);
        }
    }

    //모든 입구 오픈
    public void OpenEnterance()
    {
        foreach (GameObject re in roomEnterance)
        {
            re.GetComponent<Collider2D>().isTrigger = true;
        }
    }

    //모든 입구 봉쇄
    public void CloseEnterance()
    {
        foreach (GameObject re in roomEnterance)
        {
            re.GetComponent<Collider2D>().isTrigger = false;
        }
    }

    //방 내 모든 몬스터 죽이기
    public void KillAllMonstersInRoom()
    {
        for(int i = monsterList.Count - 1; i >= 0; i--)
        {
            monsterList[i].SetActive(false);
        }
    }

    //클리어 여부 체크
    public void CheckClear(GameObject monster)
    {
        monsterList.Remove(monster);
        if(monsterList.Count == 0)
        {
            RoomClear();
            MonsterBase.OnMonsterDied -= CheckClear;
        }
    }

    //클리어 시 실행되는 함수
    public void RoomClear()
    {
        isCleared = true;
        OpenEnterance();
    }

    //지나온 길 표시하는 함수
    public void PaintPath()
    {
        if(!miniMapSquare.activeSelf)
        {
            miniMapSquare.SetActive(true);
        }
    }

    //방안에 플레이어가 있으면 표시해주는 함수
    public void PaintCurrentPos()
    {
        if (!currentPlayerPosSquare.activeSelf)
        {
            currentPlayerPosSquare.SetActive(true);
        }
    }

    //방안에 플레이어가 없으면 지워주는 함수
    public void EraseCurrentPos()
    {
        if (currentPlayerPosSquare.activeSelf)
        {
            currentPlayerPosSquare.SetActive(false);
        }
    }
}
  • MapCreator.cs 
using System;
using System.Collections.Generic;
using UnityEngine;

public class MapCreator : MonoBehaviour
{
    [Header("맵 안에서 쓰일 방 리스트 : 일반 방")]
    public List<Room> roomPrefabs;

    [Header("맵 안에서 쓰일 방 리스트 : 엘리트 방")]
    public List<Room> roomElitePrefabs;

    [Header("맵 안에서 쓰일 방 : 보스 방")]
    public Room rooBossPrefab;

    [Header("맵 생성 후 맵으로 구성된 방들")]
    public List<Room> roomMap;

    [Header("맵 안의 한변에 있을 방 개수 (정사각형)")]
    public int mapLength;

    [Header("방 사이 간격")]
    [SerializeField]
    private int roomInterval;

    [Header("현재 있는 방의 번호")]
    [SerializeField]
    private int currentRoomNum;

    //플레이어 이동시키는 Action
    public static Action<Direction> teleportAction;

    public PlayerController playerController;

    private void Start()
    {
        mapLength = 5; 
        roomInterval = 30;

        //초기 시작
        currentRoomNum = 0;
        teleportAction += Teleport;

        CreateMap();

        playerController.transform.position = roomMap[0].spawnPoint[1].position;
        ShowPlayerPosition();
    }

    //맵 생성
    void CreateMap()
    {
        for (int i = 0; i < mapLength; i++)
        {
            for (int j = 0; j < mapLength; j++)
            {
                Room room;
                if (i + j == mapLength - 1)
                {
                    room = roomElitePrefabs[UnityEngine.Random.Range(0, roomElitePrefabs.Count)];
                }
                else if(i == mapLength - 1 && j == mapLength - 1)
                {
                    room = rooBossPrefab;
                }
                else
                {
                    room = roomPrefabs[UnityEngine.Random.Range(0, roomPrefabs.Count)];
                }
                var now = Instantiate(room, this.transform.position + new Vector3((room.roomLength + roomInterval) * j,
                    (room.roomLength + roomInterval) * i, 0), Quaternion.identity, this.transform);
                CheckEnterance(now, i, j);
                roomMap.Add(now);
            }
        }
    }

    //입구 관리
    void CheckEnterance(Room room, int height, int width)
    {
        //위쪽 입구 봉쇄
        if (height == mapLength - 1)
        {
            room.ControlEnterance(Direction.Up);
        }
        //밑쪽 입구 봉쇄
        else if (height == 0)
        {
            room.ControlEnterance(Direction.Down);
        }

        //왼쪽 입구 봉쇄
        if (width == 0)
        {
            room.ControlEnterance(Direction.Left);
        }
        //오른쪽 입구 봉쇄
        else if (width == mapLength - 1)
        {
            room.ControlEnterance(Direction.Right);
        }
    }

    //방간의 이동 구현
    public void Teleport(Direction dir)
    {
        if (!roomMap[currentRoomNum].isCleared)
        {
            return;
        }
        ErasePlayerPosition();
        switch (dir)
        {
            case Direction.Up:
                currentRoomNum += mapLength;
                playerController.transform.position = roomMap[currentRoomNum].spawnPoint[1].position;
                break;
            case Direction.Down:
                currentRoomNum -= mapLength;
                playerController.transform.position = roomMap[currentRoomNum].spawnPoint[0].position;
                break;
            case Direction.Left:
                currentRoomNum -= 1;
                playerController.transform.position = roomMap[currentRoomNum].spawnPoint[3].position;
                break;
            case Direction.Right:
                currentRoomNum += 1;
                playerController.transform.position = roomMap[currentRoomNum].spawnPoint[2].position;
                break;
            default: break;
        }
        ShowPlayerPosition();
    }

    //현재 방에 있는 모든 몬스터 죽이기
    public void KillMostersInCurrentRoom()
    {
        roomMap[currentRoomNum].KillAllMonstersInRoom();
    }

    //현재 방에 있는 입구 개방 
    public void OpenEnteranceInCurrentRoom()
    {
        roomMap[currentRoomNum].OpenEnterance();
    }

    //현재 방에 있는 입구 봉쇄
    public void BlockEnteranceInCurrentRoom()
    {
        roomMap[currentRoomNum].CloseEnterance();
    }

    //현재 맵에 있는 모든 몬스터 죽이기
    public void KillMosters()
    {
        foreach (Room room in roomMap)
        {
            room.KillAllMonstersInRoom();
        }
    }

    //모든 방의 입구 개방
    public void OpenAllRooms()
    {
        foreach (Room room in roomMap)
        {
            room.RoomClear();
        }
    }

    //모든 방의 입구 봉쇄
    public void BlockAllRooms()
    {
        foreach (Room room in roomMap)
        {
            room.CloseEnterance();
            room.isCleared = false;
        }
    }

    //즉시 보스방으로 텔레포트
    public void TeleportToBossRoom()
    {
        currentRoomNum = roomMap.Count - 1;
        playerController.transform.position = roomMap[currentRoomNum].spawnPoint[1].position;
    }

    //미니맵에 현재 위치 표시
    public void ShowPlayerPosition()
    {
        roomMap[currentRoomNum].PaintPath();
        roomMap[currentRoomNum].PaintCurrentPos();
    }

    //미니맵에 현재 위치 지우기
    public void ErasePlayerPosition()
    {
        roomMap[currentRoomNum].EraseCurrentPos();
    }
}

 

 

 

 

 

해당 기능을 끝으로 내 역할은 거의 마무리 된것 같다. 이제 해당 프로젝트의 발표와 최종 프로젝트만이 남아있다. 남은 기간도 열심히 해야겠다.