프로젝트/건즈앤 레이첼스

[유니티 프로젝트] 맵 텔레포트 카메라 이동 및 맵 외곽의 void 만들기

Bueong_E 2023. 3. 26. 23:16
반응형
SMALL

 

추가 구현 사항

  •  맵의 거리를 벌려 void 구간 생성, 맵이 붙어 있지 않기 때문에 바로 옆에 맵이 보이는 경우는 없음
    • 만약 맵의 사이즈가 다양해지거나 혹은 맵의 모양이 바뀌어도 기본 32X32 사이즈를 지킨다면 큰 문제없음
  • 맵 생성후 맵의 활성 상태  OFF 및 포탈로 옆방 접근시 방 활성상태 ON
  • 맵의 포탈에 접근시 바로 이동되는 것이 아닌 애니메이션이 작동할 시간을 벌수있게 하였다. 코루틴을 이용해 조절 하였다.

Main -  제법 코드가 길어져 코드 정리 필요

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class DungeonSceneMain : MonoBehaviour
{
    [SerializeField]
    private UIMapGenDirector UIdirector;
    [SerializeField]
    private MapGenerator generator;
    [SerializeField]
    public GameObject player;

    public Action<Vector2, string> getPortalInfo;
    public Action setPlayer;

    private bool isPlayerSpawned = false;

    void Awake()
    {
       
        while (true)
        {          
            this.generator.Init();
            if (this.generator.wholeRoomList.Count <= Math.Ceiling((this.generator.maxCol * this.generator.maxRow) * 0.5)) break;
            for (int i = 0; i < this.generator.wholeRoomList.Count; i++) Destroy(this.generator.wholeRoomList[i]);
        }

        this.UIdirector.Init();

        this.setPlayer = () =>
        {
            var startRoomTrans = this.generator.wholeRoomList.Find(x => x.transform.name.Contains("Start")).transform;
            if(!this.isPlayerSpawned)
            {
                this.player = Instantiate(this.player, startRoomTrans);
                this.isPlayerSpawned = true;
            }
            else if (this.isPlayerSpawned)
            {
                this.player.transform.parent = startRoomTrans;
            }
            this.player.transform.localPosition = Vector2.zero;
            this.UIdirector.currentPlayerMapPos = startRoomTrans.position;
        };

        this.setPlayer();

        this.getPortalInfo = (originPos, portalName) =>
        {
            this.player.gameObject.SetActive(false);
            this.StartCoroutine(this.PlayerTransferToRoom(originPos, portalName));   
        };
    }
    private IEnumerator PlayerTransferToRoom(Vector2 originPos, string portalName)
    {       
            yield return new WaitForSeconds(1f);
            this.player.gameObject.SetActive(true);   
            if (portalName.Contains("0"))
            {
                int objIndex = this.generator.wholeRoomList.FindIndex(obj => (Vector2)obj.transform.position == new Vector2(originPos.x, originPos.y + this.generator.mapDist));
                this.generator.wholeRoomList[objIndex].gameObject.SetActive(true);
                var spawnPos = this.generator.wholeRoomList[objIndex].transform.GetChild(2).position;
                this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
                this.player.transform.position = new Vector2(spawnPos.x, spawnPos.y + 2);
                this.UIdirector.currentPlayerMapPos = this.generator.wholeRoomList[objIndex].transform.position;

            }
            else if (portalName.Contains("1"))
            {
                int objIndex = this.generator.wholeRoomList.FindIndex(obj => (Vector2)obj.transform.position == new Vector2(originPos.x + this.generator.mapDist, originPos.y));
                this.generator.wholeRoomList[objIndex].gameObject.SetActive(true);
                var spawnPos = this.generator.wholeRoomList[objIndex].transform.GetChild(3).position;
                this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
                this.player.transform.position = new Vector2(spawnPos.x + 1, spawnPos.y);
                this.UIdirector.currentPlayerMapPos = this.generator.wholeRoomList[objIndex].transform.position;
            }
            else if (portalName.Contains("2"))
            {
                int objIndex = this.generator.wholeRoomList.FindIndex(obj => (Vector2)obj.transform.position == new Vector2(originPos.x, originPos.y - this.generator.mapDist));
                this.generator.wholeRoomList[objIndex].gameObject.SetActive(true);
                var spawnPos = this.generator.wholeRoomList[objIndex].transform.GetChild(0).position;
                this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
                this.player.transform.position = new Vector2(spawnPos.x, spawnPos.y - 1);
                this.UIdirector.currentPlayerMapPos = this.generator.wholeRoomList[objIndex].transform.position;
            }
            else if (portalName.Contains("3"))
            {
                int objIndex = this.generator.wholeRoomList.FindIndex(obj => (Vector2)obj.transform.position == new Vector2(originPos.x - this.generator.mapDist, originPos.y));
                this.generator.wholeRoomList[objIndex].gameObject.SetActive(true);
                var spawnPos = this.generator.wholeRoomList[objIndex].transform.GetChild(1).position;
                this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
                this.player.transform.position = new Vector2(spawnPos.x - 1, spawnPos.y);
                this.UIdirector.currentPlayerMapPos = this.generator.wholeRoomList[objIndex].transform.position;
            }          
        
    }

  
}

UIDirector - 이쪽도 코드가 길어지기 때문에 코드 정리 필요 (실제 게임 프로토 타입 제작시에는 필요 없는 부분이 많기 때문에 잘라내야 할듯하다)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using UnityEngine.Tilemaps;
using System.Linq;

public class UIMapGenDirector : MonoBehaviour
{
    public MapGenerator generator;
    public DungeonSceneMain main;

    public Button btnMapReGen;
    public TMP_Text txtMapCount;

    public Button btnHiddenRoom;
    public Text txtHiddenRoom;


    public Button btnMaxRowPlus;
    public Button btnMaxRowMinus;


    public Button btnMaxColPlus;
    public Button btnMaxColMinus;

    public TMP_Text txtRowCol;

    public Camera mainCamera;
    public Camera miniMapCam;

    public Vector3 currentPlayerMapPos;
    public GameObject imgCurrentMap;


    public void Init()
    {

        this.txtMapCount.text = string.Format("Map Count : {0}", this.generator.wholeRoomList.Count);
        this.imgCurrentMap = Instantiate(this.imgCurrentMap);
        this.StartCoroutine(this.mapFlickerling());
        this.txtRowCol.text = string.Format("MaxRow  : {0}\nMaxCol  : {1} ", this.generator.maxRow, this.generator.maxCol);
        this.AdjustFOV();

        this.btnMapReGen.onClick.AddListener(() =>
        {
            this.main.player.transform.parent = null;   
            while (true)
            {
                //maps = GameObject.FindGameObjectsWithTag("UsingRoom").ToList();
                //maps = this.generator.wholeRoomList;
                for (int i = 0; i < this.generator.wholeRoomList.Count; i++) Destroy(this.generator.wholeRoomList[i]);
                this.generator.Init();
                if (this.generator.wholeRoomList.Count <= (double)this.generator.maxCol * this.generator.maxRow / 0.5) break;
            }
            this.main.setPlayer();
            //for (int i = 0; i < maps.Count; i++) { Destroy(maps[i]); }
            this.txtMapCount.text = string.Format("Map Count : {0}", this.generator.wholeRoomList.Count);
            this.AdjustFOV();
        });

        this.btnHiddenRoom.onClick.AddListener(() =>
        {
            this.generator.isHiddenRoom = !this.generator.isHiddenRoom;

            if (this.generator.isHiddenRoom) this.txtHiddenRoom.text = "Hidden Room ON";
            else this.txtHiddenRoom.text = "Hidden Room OFF";
        });

        this.btnMaxRowPlus.onClick.AddListener(() =>
        {
            this.generator.maxRow++;
            this.txtRowCol.text = string.Format("MaxRow  : {0}\nMaxCol  : {1} ", this.generator.maxRow, this.generator.maxCol);
        });

        this.btnMaxRowMinus.onClick.AddListener(() =>
        {
            this.generator.maxRow--;
            this.txtRowCol.text = string.Format("MaxRow  : {0}\nMaxCol  : {1} ", this.generator.maxRow, this.generator.maxCol);
        });

        this.btnMaxColPlus.onClick.AddListener(() =>
        {
            this.generator.maxCol++;
            this.txtRowCol.text = string.Format("MaxRow  : {0}\nMaxCol  : {1} ", this.generator.maxRow, this.generator.maxCol);
        });

        this.btnMaxColMinus.onClick.AddListener(() =>
        {
            this.generator.maxCol--;
            this.txtRowCol.text = string.Format("MaxRow  : {0}\nMaxCol  : {1} ", this.generator.maxRow, this.generator.maxCol);
        });

    }

    private void LateUpdate()
    {
        if(this.main.player.activeSelf) 
        {
            var playerPos = main.player.transform.position;
            this.miniMapCam.transform.position = new Vector3(playerPos.x, playerPos.y, -500);
            this.imgCurrentMap.transform.position = new Vector3(this.currentPlayerMapPos.x + 7, this.currentPlayerMapPos.y + 10, -22);
            this.mainCamera.transform.position = new Vector3(playerPos.x, playerPos.y, -10);
        }      
    }

    private IEnumerator mapFlickerling()
    {
        while (true)
        {
            this.imgCurrentMap.SetActive(false);
            yield return new WaitForSeconds(1f);
            this.imgCurrentMap.SetActive(true);
            yield return new WaitForSeconds(1f);
        }
    }

    private void AdjustFOV()
    {
        //float mapSize = Mathf.Max(this.MapGenerator.maxCol, this.MapGenerator.maxRow) * 32f; // 타일맵 전체 크기 계산
        //float distance = mapSize / (2f * Mathf.Tan(defaultFOV * 0.5f * Mathf.Deg2Rad)); // 카메라와 타일맵 사이의 거리 계산
        //float requiredFOV = 2f * Mathf.Atan(mapSize / (2f * distance)) * Mathf.Rad2Deg; // 필요한 FOV 값 계산
        //this.mainCamera.fieldOfView = requiredFOV; // FOV 값을 조정하여 메인 카메라에 적용

    }
}

Generator - 이쪽도 정리가 필요할듯

using UnityEngine;
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using static AstarLogic;
using System.Collections;
using Unity.VisualScripting;
using UnityEditor.Experimental.GraphView;

public class MapGenerator : MonoBehaviour
{
    public AstarLogic astarLogic;

    public int maxRow;
    public int maxCol;
    public int mapDist = 32;

    public int mapCount;

    private Vector2[,] mapVectorPos;

    private List<GameObject> normalRoomList = new List<GameObject>();
    public List<GameObject> wholeRoomList = new List<GameObject>();

    public GameObject startRoom;
    public GameObject BossRoom;
    public GameObject normalRoom;
    public GameObject safeHouseRoom;
    public GameObject hiddemRoom;

    public GameObject portal;
    public GameObject bossPortal;
    public GameObject safeRoomPortal;
    public GameObject nextStagePortal;

    public Vector2 startRoomPos;
    public Vector2 BossRoomPos;
    public Vector2 safeHousePos;
    public Vector2 hiddemRoomPos;

    private int[,] mapLocation;

    public bool isHiddenRoom = false;

    public void Init()
    {
        StringBuilder sb = new StringBuilder();

        // 맵의 정보를 저장할 2차원 배열 선언
        this.mapLocation = new int[maxRow, maxCol];

        // 맵의 벡터 정보를 저장하는 배열 생성
        this.mapVectorPos = new Vector2[maxRow, maxCol];

        // 전체 맵을 저장하는 배열 생성
        this.wholeRoomList.Clear(); 

        //일반룸들만을 모아둔 리스트 생성
        this.normalRoomList.Clear();

        int x = 0;
        int y = 0;
        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                this.mapVectorPos[i, j] = new Vector2(x, y);
                sb.Append(string.Format("{0}.{1}({2},{3})\t", i, j, x, y));
                x += this.mapDist;
            }
            y -= this.mapDist;
            x = 0;
            sb.Append('\n');
        }

        Debug.LogFormat(sb.ToString());
        sb.Clear();

        //랜덤 포인트 만들기
        this.MakeRanLocation();

        // 만든 랜덤 포인트 들을 임시리스트에 저장
        List<Vector2> temp = new List<Vector2>();

        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                if (this.mapLocation[i, j] == 1)
                {
                    temp.Add(new Vector2(j * this.mapDist, i * -this.mapDist));
                    sb.Append(string.Format("{0}.{1}({2},{3})\t", i, j, j * this.mapDist, i * -this.mapDist));
                }

            }
        }

        Debug.LogFormat("====생성된 랜덤 좌표들 갯수 :{0}====", temp.Count);
        Debug.LogFormat(sb.ToString());
        sb.Clear();


        // 리스트에서 가장 거리가 먼 두 점을찾아 내림차순으로 넣은 Vecotr2 리스트 생성
        var furthestPoints = FindFurthestPoints(temp);

        //스타트 Vector2 포지션
        this.startRoomPos = furthestPoints[0];
        // 보스룸 Vector2 포지션
        this.BossRoomPos = furthestPoints[1];
        //안전가옥 Vector2 포지션
        if(this.maxCol*this.maxRow <= 6)
        {
            this.safeHousePos = furthestPoints[furthestPoints.Count - 1];

        }
        else
        {
            this.safeHousePos = furthestPoints[furthestPoints.Count - 2];
        }
      
        //시작룸 생성
        var startRoomGo = GameObject.Instantiate(this.startRoom);
        startRoomGo.transform.position = this.startRoomPos;
        this.wholeRoomList.Add(startRoomGo);

        //보스룸 생성
        var bossRoomGo = GameObject.Instantiate(this.BossRoom);
        bossRoomGo.transform.position = this.BossRoomPos;
        this.wholeRoomList.Add(bossRoomGo);

        //안전가옥 생성
        var safeHouseGo = GameObject.Instantiate(this.safeHouseRoom);
        safeHouseGo.transform.position = this.safeHousePos;
        this.wholeRoomList.Add(safeHouseGo);

        //임시 리스트 초기화
        temp.Clear();
        temp.Add(this.startRoomPos);
        temp.Add(this.BossRoomPos);
        temp.Add(this.safeHousePos);


        //2차원 맵 배열에서 실제로 방이 없는 곳 초기화

        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                if (this.mapLocation[i, j] == 1)
                {
                    if (!temp.Contains(new Vector2(j * this.mapDist, i * -this.mapDist)))
                    {
                        this.mapLocation[i, j] = 0;
                    }
                }
            }
        }

        int startY = 0;
        int startX = 0;

        int bossY = 0;
        int bossX = 0;

        int safeY = 0;
        int safeX = 0;


        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                if (this.mapVectorPos[i, j] == this.startRoomPos)
                {
                    this.mapLocation[i, j] = 2;
                    Debug.LogFormat("<color=green>시작룸 위치 : {0},{1} vectorList 값 : {2}</color>", i, j, this.mapVectorPos[i, j]); ; ;
                    startY = i;
                    startX = j;
                }
                else if (this.mapVectorPos[i, j] == this.BossRoomPos)
                {
                    this.mapLocation[i, j] = 4;
                    Debug.LogFormat("<color=red>보스룸 위치 : {0},{1} vectorList 값 : {2}</color>", i, j, this.mapVectorPos[i, j]);
                    bossY = i;
                    bossX = j;
                }
                else if (this.mapVectorPos[i, j] == this.safeHousePos)
                {
                    this.mapLocation[i, j] = 3;
                    Debug.LogFormat("<color=blue>안전가옥 위치 : {0},{1} vectorList 값 : {2}</color>", i, j, this.mapVectorPos[i, j]);
                    safeY = i;
                    safeX = j;
                }
            }
        }


        List<AStarNode> toBossList = new List<AStarNode>();

        this.astarLogic.Init(this.maxRow, this.maxCol, startX, startY, bossX, bossY, out toBossList);

        toBossList.ForEach(t => { Debug.LogFormat("보스 방까지의 노드 리스트 :{0} , {1}", t.y, t.x); });

        List<AStarNode> toSafeHouseList = new List<AStarNode>();

        this.astarLogic.Init(this.maxRow, this.maxCol, safeX, safeY, startX, startY, out toSafeHouseList);

        toSafeHouseList.ForEach(t => { Debug.LogFormat("안전 가옥 부터 스타트 까지의 노드 리스트 :{0} , {1}", t.y, t.x); });



        //보스방 까지의 일반 룸 생성
        foreach (AStarNode node in toBossList)
        {
            var checkVec = new Vector2(node.x * this.mapDist, node.y * -this.mapDist);
            if (checkVec == this.startRoomPos || checkVec == this.BossRoomPos || checkVec == this.safeHousePos) continue;
            else
            {
                //생성후 포지션 잡아주기
                var go = GameObject.Instantiate(this.normalRoom);
                go.transform.position = new Vector2(node.x * this.mapDist, node.y * -this.mapDist);
                //2차원 맵 배열에 표시
                this.mapLocation[node.y, node.x] = 1;
                //일반룸 리스트에 목록 추가
                this.normalRoomList.Add(go);
                this.wholeRoomList.Add(go);
                sb.Append(String.Format("({0},{1}) {2}", node.y, node.x, checkVec));
            }
        }

        Debug.Log("====보스방까지 생성된 일반룸 목록 ====");
        Debug.Log(sb.ToString());
        sb.Clear();

        //세이프 하우스 부터 스타트 룸 까지의 일반 룸 생성
        foreach (AStarNode node in toSafeHouseList)
        {
            var checkVec = new Vector2(node.x * this.mapDist, node.y * -this.mapDist);
            if (this.mapLocation[node.y, node.x] != 0 || checkVec == this.startRoomPos || checkVec == this.BossRoomPos || checkVec == this.safeHousePos) continue;
            else
            {
                //생성후 포지션 잡아주기
                var go = GameObject.Instantiate(this.normalRoom);
                go.transform.position = new Vector2(node.x * this.mapDist, node.y * -this.mapDist);
                //2차원 맵 배열에 표시
                this.mapLocation[node.y, node.x] = 1;
                //일반룸 리스트에 목록 추가
                this.normalRoomList.Add(go);
                this.wholeRoomList.Add(go);
                sb.Append(String.Format("({0},{1}) {2}", node.y, node.x, checkVec));
            }
        }

        Debug.Log("====다시 시작지점까지 생성된 일반룸 목록 ====");
        Debug.Log(sb.ToString());
        sb.Clear();

        if (this.isHiddenRoom)
        {
            this.MakeHiddenRoom();
        }


        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                sb.Append(string.Format("<color=pink>({0},{1}) : {2}</color>\t", i, j, this.mapLocation[i, j]));
                if (this.mapLocation[i, j] != 0)
                {
                    this.mapCount++;
                }
            }
        }
        Debug.LogFormat("====최종 배열====");
        Debug.LogFormat(sb.ToString());

        this.MakePortal();
        this.DeActiveMaps();
    }

    private void MakeRanLocation()
    {
        int cunt = 0;
        while (cunt != Math.Ceiling((double)(this.maxCol * this.maxRow) / 2))
        {
            var Y = UnityEngine.Random.Range(0, this.maxRow);
            var X = UnityEngine.Random.Range(0, this.maxCol);
            if (this.mapLocation[Y, X] == 1)
            {
                continue;
            }
            else
            {
                this.mapLocation[Y, X] = 1;
                cunt++;
            }
        }
    }

    private List<Vector2> FindFurthestPoints(List<Vector2> points)
    {
        // 리스트에서 가능한 모든 두 점 쌍을 생성한다.
        var pairs = from p1 in points
                    from p2 in points
                    where p1 != p2
                    select new { p1, p2 };

        // 각 쌍의 거리를 계산
        var distances = pairs.Select(pair => new { pair.p1, pair.p2, distance = Vector2.Distance(pair.p1, pair.p2) });

        // 거리가 가장 먼 두 점을 찾는다.
        var furthestPoints = distances.OrderByDescending(pair => pair.distance).First();


        var top2List = new List<Vector2> { furthestPoints.p1, furthestPoints.p2 };

        //새로운 리스트 생성
        var sortedList = new List<Vector2>();
        sortedList.Add(top2List[0]);
        sortedList.Add(top2List[1]);
        sortedList.AddRange(points.Except(top2List).OrderBy(p => Vector2.Distance(top2List[0], p)));

        return sortedList;
    }

    private void MakeHiddenRoom()
    {
        //노말룸리스트인덱스 중 랜덤 인덱스 설정
        var num = UnityEngine.Random.Range(0, this.normalRoomList.Count - 1);
        //랜덤 인덱스위치에 히든룸 생성
        var hiddenGO = UnityEngine.Object.Instantiate(this.hiddemRoom);
        this.wholeRoomList.Add(hiddenGO);
        //히든룸 포지션에 랜덤룸 포지션 담기 및 위치 변경
        this.hiddemRoomPos = this.normalRoomList[num].transform.position;
        hiddenGO.transform.position = this.hiddemRoomPos;
        //기존 위치에 있던 노말룸 제거
        Debug.LogFormat("파괴된 노말룸 포지션 {0}", this.hiddemRoomPos);
        Destroy(this.normalRoomList[num]);
        this.normalRoomList.Remove(this.normalRoomList[num]);
        this.wholeRoomList.Remove(this.wholeRoomList.Find(x => (Vector2)x.transform.position == this.hiddemRoomPos));
    }

    private void MakePortal()
    {
        //포탈 생성
        for (int i = 0; i < this.maxRow; i++)
        {
            for (int j = 0; j < this.maxCol; j++)
            {
                // 기준방 발견 
                if (this.mapLocation[i, j] != 0)
                {
                    //배열을 벗어나지 않는다면 윗칸 보기
                    if (i - 1 >= 0)
                    {
                        //벗어나지 않았는데 방이 있다면
                        if (this.mapLocation[i - 1, j] != 0)
                        {
                            //생성된 룸 리스트에서 현재 검색중인 배열과 같은 위치에 있는 룸 찾기
                            foreach (var room in this.wholeRoomList)
                            {
                                if ((Vector2)room.transform.position == new Vector2(j * this.mapDist, i * -this.mapDist))
                                {
                                    GameObject go = null;
                                    //찾으면 포탈 생성해서 해당 포인트에 자식으로 넣어주고 로컬 포지션 0으로 초기화
                                    if (this.mapLocation[i - 1, j] == 4)
                                    {
                                        go = Instantiate(this.bossPortal, room.transform.GetChild(0)); // 보스룸
                                    }
                                    else if (this.mapLocation[i - 1, j] == 3)
                                    {
                                        go = Instantiate(this.safeRoomPortal, room.transform.GetChild(0)); //상점
                                    }
                                    else
                                    {
                                        go = Instantiate(this.portal, room.transform.GetChild(0)); // 일반룸
                                    }
                                    go.transform.localPosition = Vector2.zero;
                                }
                            }
                        }
                    }
                    //배열을 벗어나지 않는다면 아랫칸 보기
                    if (i + 1 < this.maxRow)
                    {
                        //벗어나지 않았는데 방이 있다면
                        if (this.mapLocation[i + 1, j] != 0)
                        {
                            //생성된 룸 리스트에서 현재 검색중인 배열과 같은 위치에 있는 룸 찾기
                            foreach (var room in this.wholeRoomList)
                            {
                                if ((Vector2)room.transform.position == new Vector2(j * this.mapDist, i * -this.mapDist))
                                {
                                    GameObject go = null;
                                    //찾으면 포탈 생성해서 해당 포인트에 자식으로 넣어주고 로컬 포지션 0으로 초기화
                                    if (this.mapLocation[i + 1, j] == 4)
                                    {
                                        go = Instantiate(this.bossPortal, room.transform.GetChild(2)); // 보스룸
                                    }
                                    else if (this.mapLocation[i + 1, j] == 3)
                                    {
                                        go = Instantiate(this.safeRoomPortal, room.transform.GetChild(2)); //상점
                                    }
                                    else
                                    {
                                        go = Instantiate(this.portal, room.transform.GetChild(2)); // 일반룸
                                    }
                                    go.transform.localPosition = Vector2.zero;
                                }
                            }
                        }
                    }
                    //배열을 벗어나지 않는다면 오른쪽 칸 보기
                    if (j + 1 < this.maxCol)
                    {
                        //벗어나지 않았는데 방이 있다면
                        if (this.mapLocation[i, j + 1] != 0)
                        {
                            //생성된 룸 리스트에서 현재 검색중인 배열과 같은 위치에 있는 룸 찾기
                            foreach (var room in this.wholeRoomList)
                            {
                                if ((Vector2)room.transform.position == new Vector2(j * this.mapDist, i * -this.mapDist))
                                {
                                    GameObject go = null;
                                    //찾으면 포탈 생성해서 해당 포인트에 자식으로 넣어주고 로컬 포지션 0으로 초기화
                                    if (this.mapLocation[i, j + 1] == 4)
                                    {
                                        go = Instantiate(this.bossPortal, room.transform.GetChild(1)); // 보스룸
                                    }
                                    else if (this.mapLocation[i, j + 1] == 3)
                                    {
                                        go = Instantiate(this.safeRoomPortal, room.transform.GetChild(1)); //상점
                                    }
                                    else
                                    {
                                        go = Instantiate(this.portal, room.transform.GetChild(1)); // 일반룸
                                    }
                                    go.transform.localPosition = Vector2.zero;
                                }
                            }
                        }
                    }
                    //배열을 벗어나지 않는다면 왼쪽 칸 보기
                    if (j - 1 >= 0)
                    {
                        //벗어나지 않았는데 방이 있다면
                        if (this.mapLocation[i, j - 1] != 0)
                        {
                            //생성된 룸 리스트에서 현재 검색중인 배열과 같은 위치에 있는 룸 찾기
                            foreach (var room in this.wholeRoomList)
                            {
                                if ((Vector2)room.transform.position == new Vector2(j * this.mapDist, i * -this.mapDist))
                                {
                                    GameObject go = null;
                                    //찾으면 포탈 생성해서 해당 포인트에 자식으로 넣어주고 로컬 포지션 0으로 초기화
                                    if (this.mapLocation[i, j - 1] == 4)
                                    {
                                        go = Instantiate(this.bossPortal, room.transform.GetChild(3)); // 보스룸
                                    }
                                    else if (this.mapLocation[i, j - 1] == 3)
                                    {
                                        go = Instantiate(this.safeRoomPortal, room.transform.GetChild(3)); //상점
                                    }
                                    else
                                    {
                                        go = Instantiate(this.portal, room.transform.GetChild(3)); // 일반룸
                                    }
                                    go.transform.localPosition = Vector2.zero;
                                }
                            }
                        }
                    }
                }

            }
        }
        var trans = this.wholeRoomList.Find(x => x.gameObject.name.Contains("Boss")).transform.GetChild(4).transform;
        Instantiate(this.nextStagePortal, trans);  
    }

    private void DeActiveMaps()
    {
        for(int i = 0;  i < this.wholeRoomList.Count; i++)
        {
            if (this.wholeRoomList[i].name.Contains("Start")) continue;
            else
            {
                this.wholeRoomList[i].gameObject.SetActive(false);
            }
        }  
    }
}

portalController

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PortalController : MonoBehaviour
{
    [SerializeField]
    private DungeonSceneMain main;

    public enum PotalType
    {
        Normal,
        SafeRoomPortal,
        BossPortal,
        NextStagePortal
    }

    public PotalType type;

    private void Awake()
    {
        this.main = GameObject.Find("DungeonSceneMain").GetComponent<DungeonSceneMain>();
        if(this.type == PotalType.NextStagePortal)
        {
            this.GetComponent<BoxCollider2D>().enabled = false;
            this.StartCoroutine(this.WaitforGenerate());
        }  
    }

    private IEnumerator WaitforGenerate()
    {
        //다음 스테이지로 가는 포탈이 생성되는 애니메이션이 끝날때 까지 기다림
        yield return new WaitForSeconds(2f);
        this.GetComponent<BoxCollider2D>().enabled = true;
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
          
        if(collision.gameObject.tag == "Player")
        {
            if (this.type == PotalType.NextStagePortal)
            {
                Debug.Log("다음 스테이지로");
            }
            else
            {               
                var parentPos = this.transform.parent.parent.position;
                var protalName = this.transform.parent.name;
                this.main.getPortalInfo(parentPos, protalName);
            }            
        }
    }
}

 

맵의 갯수를 좀더 유연하게 조절할수 있는 방법을 고려해 보아야겠다.

 

또 이번에 패키지 import 를 했는데 기존에 작업한 작업물이 덮어 씌워지는 일이 있어 해당 코드를 기존에 만들어 두었던 코드로 변경하는데 시간을 너무 써버렸다 ㅠㅠ 

앞으로 백업을 생활화 하고 패키지를 import 한다면 좀 더 신중하게 내용물을 확인하고 백업을 미리 해두는 습관을 가져야겠다.

 

 

 

반응형
LIST