차주중으로 프로젝트를 합칠 예정인지라 지금까지 만든 맵 제너레이터와 던전씬 메인 그리고 NPC 들의 스크립트를 합쳐 프로젝트를 정리중이다.
우선 안전가옥과 히든룸의 NPC 배치 및 구현이 완료되었다.
포탈 또한 이전에 사용하던 임시 포탈이 아닌 최종 에셋 용 포탈로 변경하였으며 시작룸 및 보스룸, 일반룸들은 컨텐츠 제작 단계에서 여러개로 제작 예정이다.
현재 구조로는 앱씬 -> 타이틀 씬 -> 로딩씬 -> 성소씬 -> 로딩씬 -> 던전씬 -> 로딩씬 -> 성소씬 -> 로딩씬 -> 던전씬 ......
순으로 씬 전환 예정이며 플레이어는 1윤회를 완료할때 까지 성소와 던전을 드나들며 성장 및 전투를 즐길수 있도록 레벨 디자인을 계획중이다.
코드는 이전에 구조가 잡히지 않았을때보다 정리가 많이 되었으며 현재까지 큰 버그나 문제가 없어 다행인 부분이지만 프로젝트들을 합치며 생길 문제점들이 살짝 걱정되긴 한다.
하지만 이러한 상황을 고려해 대부분의 UI 및 오브젝트들이 다른 팀원들이 작업한 오브젝트와 통신을 할수 있도록 싱글톤 매니저들을 준비하였으며 (객체 지향을 고려해 5개 정도의 매니저만 사용) 이를 이용해 구조적으로 큰 문제는 없을 것 같다는 생각이 든다 (아직까진..)
맵의 배열 또한 다양한 모습으로 나와주어 유저가 비슷한 구성의 스테이지를 경험할 확률히 현저히 줄어들었다.
가령 아래는 1스테이지에서 유저가 경험할수 있는 맵 구성의 일부이다.
이전 포스팅에서 이야기 하였듯이 맵의 모양은 배열의 숫자에 따라 바뀐다. 위 배열들은 3~4 , 2~3 사이의 배열들 만을 사용하였고 단순히 배열 인덱스의 순서를 바꾸는 것 만으로 더 다양한 맵의 모습이 나올수 있다.
유저가 전투를 최소 1번 이상 경험하고 (흰색룸)
선택에 따라 2번째 전투 혹은 상점(파란색룸) 또는 보상룸(노란색)에 들어갈수 있고
이후 최종적으로는 보스방(빨간색룸) 에 도달할수 있도록 하였다.
좀 더 자세한 밸런싱은 직접 플레이해보며 손으로 잡아야겠지만 일단 머릿속 시나리오와 수치 밸런스 상으로는 지금이 최선인듯 하다.
아래는 코드
MapGenerator 스크립트
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 int maxRow;
public int maxCol;
public int mapDist = 32;
public List<GameObject> normalRoomList = new List<GameObject>();
public List<GameObject> wholeRoomList = new List<GameObject>();
public GameObject startRoom;
public GameObject BossRoom;
public GameObject[] forrestNormalRoom;
public GameObject safeHouseRoom;
public GameObject hiddemRoom;
public GameObject portal;
public GameObject bossPortal;
public GameObject safeRoomPortal;
public GameObject nextStagePortal;
private Vector2[,] mapVectorPos;
public Vector2 startRoomPos;
public Vector2 BossRoomPos;
public Vector2 safeHousePos;
public Vector2 hiddemRoomPos;
private int[,] mapLocation;
StringBuilder sb = new StringBuilder();
public void Init()
{
this.maxCol = UnityEngine.Random.Range(3,5); // 데이터 매니저 참고
this.maxRow = UnityEngine.Random.Range(2,4); // 데이터 매니저 참고
// 맵의 정보를 저장할 2차원 배열 선언
this.mapLocation = new int[this.maxRow, this.maxCol];
// 맵의 벡터 정보를 저장하는 배열 생성
this.mapVectorPos = new Vector2[this.maxRow, this.maxCol];
// 전체 맵을 저장하는 배열 생성
this.wholeRoomList.Clear();
//일반룸들만을 모아둔 리스트 생성
this.normalRoomList.Clear();
//벡터 리스트 제작
this.MakeVectorList();
//랜덤 포인트 만들기
this.MakeRanLocation();
// 만든 랜덤 포인트 들을 임시리스트에 저장
var temp = this.MakeTempList();
// 리스트에서 가장 거리가 먼 두 점을찾아 내림차순으로 넣은 Vecotr2 리스트 생성
var furthestPoints = this.FindFurthestPoints(temp);
this.MakeMajorRoomsPos(furthestPoints);
this.MakeMajorRooms();
//임시 리스트 초기화
temp.Clear();
temp.Add(this.startRoomPos);
temp.Add(this.BossRoomPos);
temp.Add(this.safeHousePos);
//2차원 맵 배열에서 1이지만 방이 없는 곳 초기화
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;
}
}
}
AstarLogic astarLogic = new AstarLogic();
List<AStarNode> toBossList = new List<AStarNode>();
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>();
astarLogic.Init(this.maxRow, this.maxCol, safeX, safeY, startX, startY, out toSafeHouseList);
toSafeHouseList.ForEach(t => { Debug.LogFormat("안전 가옥 부터 스타트 까지의 노드 리스트 :{0} , {1}", t.y, t.x); });
var currentStage = 1;
//보스방 까지의 일반 룸 생성
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 = default(GameObject);
var ran = UnityEngine.Random.Range(0,4);
//현재 스테이지에 따라 룸 리스트 변경
if (currentStage == 1) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if(currentStage == 2) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if(currentStage == 3) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if(currentStage == 4) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
//위치 잡기
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 = default(GameObject);
var ran = UnityEngine.Random.Range(0, 4);
//현재 스테이지에 따라 룸 리스트 변경
if (currentStage == 1) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if (currentStage == 2) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if (currentStage == 3) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
else if (currentStage == 4) { go = GameObject.Instantiate(this.forrestNormalRoom[ran]); }
//위치 잡기
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();
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]));
}
}
Debug.LogFormat("====최종 배열====");
Debug.LogFormat(sb.ToString());
sb.Clear();
// 생성됨 룸에 포탈 만들기
this.MakePortal();
// 시작룸을 제외한 모든 룸 셋 off
//this.DeActiveMaps();
}
private void MakeVectorList()
{
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();
}
private void MakeRanLocation()
{
int count = 0;
int maxCount = (this.maxCol * this.maxRow + 1) / 2;
bool[,] selectedLocations = new bool[this.maxRow, this.maxCol];
while (count < maxCount)
{
int y = UnityEngine.Random.Range(0, this.maxRow);
int x = UnityEngine.Random.Range(0, this.maxCol);
if (!selectedLocations[y, x])
{
selectedLocations[y, x] = true;
this.mapLocation[y, x] = 1;
count++;
}
}
}
private List<Vector2> MakeTempList()
{
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));
}
}
}
Debug.LogFormat("====생성된 랜덤 좌표들 갯수 :{0}====", temp.Count);
Debug.LogFormat(sb.ToString());
sb.Clear();
return temp;
}
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 MakeMajorRoomsPos(List<Vector2> FurtherList)
{
//스타트 Vector2 포지션
this.startRoomPos = FurtherList[0];
// 보스룸 Vector2 포지션
this.BossRoomPos = FurtherList[1];
//안전가옥 Vector2 포지션
if (this.maxCol * this.maxRow <= 6)
{
this.safeHousePos = FurtherList[FurtherList.Count - 1];
}
else
{
this.safeHousePos = FurtherList[FurtherList.Count - 2];
}
}
private void MakeMajorRooms()
{
//시작룸 생성
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);
}
private void MakeHiddenRoom()
{
//히든룸 생성
var hiddenGO = UnityEngine.Object.Instantiate(this.hiddemRoom);
//히든 룸 생성 후 전체룸 리스트에 추가
this.wholeRoomList.Add(hiddenGO);
//히든룸 포지션 변수에 시작 룸 위치와 가장 거리가 먼 노말 룸 위치 할당.
this.hiddemRoomPos = this.FindFurtherNormalRoomFromStart(this.startRoomPos, this.normalRoomList);
// 히든룸 위치 잡아주기.
hiddenGO.transform.position = this.hiddemRoomPos;
// 기존 위치에 있던 노말룸 파괴 (노말룸 리스트에서 찾기)
GameObject targetNoramlRoom = this.normalRoomList.Find(x => (Vector2)x.transform.position == this.hiddemRoomPos);
// 찾은 노말룸 파괴
GameObject.Destroy(targetNoramlRoom);
// 리스트에서 게임 오브젝트 인스턴스 제거
this.normalRoomList.Remove(targetNoramlRoom);
this.wholeRoomList.Remove(targetNoramlRoom);
}
private Vector2 FindFurtherNormalRoomFromStart(Vector2 start, List<GameObject> list)
{
float maxDistance = 0f;
Vector2 maxDistanceVector = Vector2.zero;
for (int i = 0; i < list.Count; i++)
{
float distance = Vector2.Distance(start, list[i].transform.position);
if (distance > maxDistance)
{
maxDistance = distance;
maxDistanceVector = list[i].transform.position;
}
}
return maxDistanceVector;
}
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);
}
}
}
private void MakePortal()
{
for (int i = 0; i < maxRow; i++)
{
for (int j = 0; j < maxCol; j++)
{
if (mapLocation[i, j] != 0)
{
var room = this.wholeRoomList.Find((x) => (Vector2)x.transform.position == new Vector2(j * this.mapDist, i * -this.mapDist));
Transform[] roomChildren = { room.transform.GetChild(0), room.transform.GetChild(2), room.transform.GetChild(1), room.transform.GetChild(3) };
for (int k = 0; k < roomChildren.Length; k++)
{
Transform roomChild = roomChildren[k];
Vector2 roomPos = (Vector2)room.transform.position;
int top = i - 1 >= 0 ? mapLocation[i - 1, j] : -1;
int bottom = i + 1 < maxRow ? mapLocation[i + 1, j] : -1;
int right = j + 1 < maxCol ? mapLocation[i, j + 1] : -1;
int left = j - 1 >= 0 ? mapLocation[i, j - 1] : -1;
int[] roomLocations = { top, bottom, right, left };
int portalType = -1;
for (int l = 0; l < roomLocations.Length; l++)
{
int location = roomLocations[l];
if (location == -1) continue;
else
{
if (location == 4 && l == k) { portalType = 0; break; }
if (location == 3 && l == k) { portalType = 1; break; }
if (location != 0 && l == k) { portalType = 2; break; }
}
}
if (portalType == 0)
{
var go = GameObject.Instantiate(this.bossPortal, roomChild);
go.transform.localPosition = Vector2.zero;
if (roomChild.gameObject.name.Contains('0')) go.transform.Rotate(new Vector3(0, 0, 90));
if (roomChild.gameObject.name.Contains('2')) go.transform.Rotate(new Vector3(0, 0, -90));
if (roomChild.gameObject.name.Contains('3')) go.transform.Rotate(new Vector3(0, 0, -180));
}
else if (portalType == 1)
{
var go = GameObject.Instantiate(this.safeRoomPortal, roomChild);
go.transform.localPosition = Vector2.zero;
if (roomChild.gameObject.name.Contains('0')) go.transform.Rotate(new Vector3(0, 0, 90));
if (roomChild.gameObject.name.Contains('2')) go.transform.Rotate(new Vector3(0, 0, -90));
if (roomChild.gameObject.name.Contains('3')) go.transform.Rotate(new Vector3(0, 0, -180));
}
else if (portalType == 2)
{
var go = GameObject.Instantiate(this.portal, roomChild);
go.transform.localPosition = Vector2.zero;
if(roomChild.gameObject.name.Contains('0')) go.transform.Rotate(new Vector3(0, 0, 90));
if(roomChild.gameObject.name.Contains('2')) go.transform.Rotate(new Vector3(0, 0, -90));
if(roomChild.gameObject.name.Contains('3')) go.transform.Rotate(new Vector3(0, 0, -180));
}
}
}
}
}
this.nextStagePortal = this.wholeRoomList.Find(x => x.gameObject.name.Contains("Boss")).transform.GetChild(4).gameObject;
}
}
DungeonSceneMain 스크립트
using System;
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class DungeonSceneMain : MonoBehaviour
{
[SerializeField]
private UIMiniMap miniMapDirector;
[SerializeField]
private UINPCPopupDirector NPCPopupDirector;
[SerializeField]
private MapGenerator generator;
[SerializeField]
public GameObject player;
[SerializeField]
private MainCameraController mainCam;
public Action<Vector2, string> getPortalInfo;
public Action setPlayer;
private bool isPlayerSpawned = false;
[Tooltip("생성하고 싶은 룸 수")]
[SerializeField]
public int roomCount;
void Awake()
{
this.InitStage();
this.miniMapDirector.Init(this.player.transform.position) ;
this.NPCPopupDirector.Init();
this.mainCam.Init();
EventDispatcher.Instance.AddListener<bool>(EventDispatcher.EventName.DungeonMainToNextStage,
this.InitStage);
EventDispatcher.Instance.AddListener<Vector2,string>(EventDispatcher.EventName.DungeonMainPlayerToNextRoom,
this.MoveToNextArea);
}
private void InitRoom()
{
//this.roomCount = 6; 인포 매니저 참고 하여 할당
while (true)
{
for (int i = 0; i < this.generator.wholeRoomList.Count; i++) { Destroy(this.generator.wholeRoomList[i]); }
this.generator.Init();
//맵 룸 수 조절하는 부분
if (this.generator.wholeRoomList.Count == this.roomCount && this.generator.normalRoomList.Count != 0) break;
}
}
/// <summary>
/// 플레이어 스테이지 이동시 실행
/// </summary>
public bool InitStage()
{
this.player.transform.parent = null;
this.InitRoom();
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.miniMapDirector.currentPlayerMapPos = startRoomTrans.position;
return true;
}
private void MoveToNextArea(Vector2 originPos , string portalName)
{
this.mainCam.isPlayerTeleporting = true;
this.player.gameObject.SetActive(false);
this.StartCoroutine(this.PlayerTransferToRoom(originPos, portalName));
}
private IEnumerator PlayerTransferToRoom(Vector2 originPos, string portalName)
{
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;
yield return new WaitForSeconds(1.5f);
this.mainCam.transform.position = new Vector3(spawnPos.x, spawnPos.y, -10);
yield return new WaitForSeconds(0.5f);
this.player.gameObject.SetActive(true);
this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
this.player.transform.position = new Vector2(spawnPos.x, spawnPos.y + 2);
this.miniMapDirector.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;
yield return new WaitForSeconds(1.5f);
this.mainCam.transform.position = new Vector3(spawnPos.x, spawnPos.y, -10);
yield return new WaitForSeconds(0.5f);
this.player.gameObject.SetActive(true);
this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
this.player.transform.position = new Vector2(spawnPos.x + 1, spawnPos.y);
this.miniMapDirector.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;
yield return new WaitForSeconds(1.5f);
this.mainCam.transform.position = new Vector3(spawnPos.x, spawnPos.y, -10);
yield return new WaitForSeconds(0.5f);
this.player.gameObject.SetActive(true);
this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
this.player.transform.position = new Vector2(spawnPos.x, spawnPos.y - 1);
this.miniMapDirector.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;
yield return new WaitForSeconds(1.5f);
this.mainCam.transform.position = new Vector3(spawnPos.x,spawnPos.y,-10);
yield return new WaitForSeconds(0.5f);
this.player.gameObject.SetActive(true);
this.player.transform.parent = this.generator.wholeRoomList[objIndex].transform;
this.player.transform.position = new Vector2(spawnPos.x - 1, spawnPos.y);
this.miniMapDirector.currentPlayerMapPos = this.generator.wholeRoomList[objIndex].transform.position;
}
this.mainCam.player = this.player;
this.mainCam.isPlayerTeleporting = false;
this.miniMapDirector.MiniMapUpdate(this.player.transform.position);
}
}
맵 생성에 가장 핵심이 되는 스크립트 두개인데 맵을 생성하고 원하는 룸수의 맵을 생성시키고 플레이어를 관리하는 스크립트 이다.
'프로젝트 > 건즈앤 레이첼스' 카테고리의 다른 글
[유니티 프로젝트] 타이틀 씬 to 던전 씬 까지 (0) | 2023.04.26 |
---|---|
[유니티 프로젝트] 허브 (성소) -> 던전 -> 허브 루프 (윤회) (1) | 2023.04.23 |
[유니티 프로젝트] 카메라 hit shaking 이펙트 & 스크린 flash 이펙트 코루틴 사용 구현 (0) | 2023.04.19 |
[유니티 프로젝트] 로그라이크 허브 마을 (기억의 성소) 제작 .3 구조잡기 - 완료 (0) | 2023.04.18 |
[유니티 프로젝트] 간단한이벤트 디스패쳐 EventDispatcher 제작 및 사용 (0) | 2023.04.17 |