Unity를 공부하면서 간단한 미로게임에 새로운 기능을 계획하고 만들어 봤습니다.
제가 생각하는 미로게임은 시작지점부터 출발하여 종료지점인 출구를 찾아 이동하는 게임입니다.
저는 이 방식에 새로운 방식을 집어 넣어봤습니다.
퍼즐 형식의 미로찾기
- 어떤 스위치를 누르면 진행해야 하는 길이 바뀐다.
- 순간 이동.
- 여러개의 스테이지가 있음.
스테이지가 여러개인 만큼 SceneManagememt를 한번 활용 해보고자 했습니다.
화면 전환.

스테이지 선택 화면 입니다. 이 곳에서 내가 원하는 스테이지로 이동할 수 있습니다.

버튼을 누르면 해당 버튼의 Text 값을 읽어와 해당하는 Scene으로 넘겨주는 함수 입니다.
게임의 진행

기본적으로 게임 기능에 관여하는 Manager는 자주 쓰이기 때문에 싱글톤으로 만들어 주었습니다.
싱글톤으로 만들어 주면 인스턴스화가 돼있기 때문에 Manager가 관리 하는 기능 함수를 사용하기 위해 따로 추가 선언을 해주지 않아도 된다.

플레이어와 필드위 아이템과의 상호작용을 맡아준다. Manager가 싱글톤으로 만들어져 있어 별도 선언 없이 호출 할 수 있다.
게임의 메인 기능 (벽의 이동, 텔레포트)
public void getStage(int stagenum, string name)
{
switch (stagenum) // 현재 플레이 중인 스테이지의 정보를 들고 해당 스테이지 로직에 보내준다.
{
case 2:
Stage2(name);
break;
case 3:
Stage3(name);
break;
}
}
public void Stage2(string name)
{
int num = name[name.Length - 1] - '0';
// 플레이어가 획득한 쥬얼의 번호를 토대로 어느 벽을 움직일 것인지 결정한다.
switch (num)
{
case 1:
Stage2Walls[0].transform.position = new Vector2(-1, 0.5f);
break;
case 2:
Stage2Walls[0].transform.position = new Vector2(0, 0.5f);
break;
case 3:
Stage2Walls[1].transform.position = new Vector2(2, -0.5f);
break;
case 4:
Stage2Walls[2].SetActive(false);
break;
}
}
public void Stage3(string name)
{
// 플레이어가 상호작용한 아이템이 쥬얼인지 텔레포트인지를 먼저 판별 한다.
// 쥬얼을 획득 했으면 획득한 쥬얼의 번호를 토대로 어느 벽을 움직일 것인지 결정한다.
if (name[0] == 'J')
{
int num = name[name.Length - 1] - '0';
switch (num)
{
case 1:
Stage3Walls[0].transform.position = new Vector2(-2, 4.5f);
break;
case 2:
Stage3Walls[0].transform.position = new Vector2(-6, 4.5f);
Stage3Walls[1].SetActive(false);
break;
case 3:
Stage3Walls[2].transform.position = new Vector2(7f, 1.5f);
Stage3Walls[2].transform.eulerAngles = new Vector3(0, 0, 0);
Stage3Walls[3].SetActive(false);
break;
case 4:
Stage3Walls[2].transform.position = new Vector2(7.5f, 1f);
Stage3Walls[2].transform.eulerAngles = new Vector3(0, 0, 90);
break;
}
}
if (name[0] == 'T')
{
// 텔레포트 기능을 수행한다.
int index = getTPindex(name);
Rigidbody2D r = Stage3TPs[index].GetComponent<Rigidbody2D>();
player.transform.position = r.position + getNextPos(r);
}
}
int getTPindex(string name) // tp의 번호와 a,b 쌍을 토대로 나갈 텔레포트의 위치를 가져온다.
{
int num = name[name.Length - 2] -'0';
int category = (num - 1) * 2 + name[name.Length - 1] - 'a';
if(category%2 == 0)
{
return category + 1;
}
else
{
return category - 1;
}
}
Vector2 getNextPos(Rigidbody2D r)
{
// 텔레포트 주변 빈 공간을 탐색하여 그 위치로 플레이어를 이동 시켜 준다.
Vector2[] dirs = { Vector2.up, Vector2.down, Vector2.right, Vector2.left };
int i = 0;
while (i < 4)
{
RaycastHit2D rayhit;
Debug.DrawRay(r.position, dirs[i]);
rayhit = Physics2D.Raycast(r.position, dirs[i], 0.5f, LayerMask.GetMask("wall"));
if (rayhit.collider == null)
{
break;
}
i++;
}
return dirs[i];
}
플레이어가 쥬얼을 획득하면 해당 쥬얼에 연결된 벽을 움직인다. 이로 인해 퍼즐을 푸는 느낌을 받을 수 있다.
텔레포트는 두 텔레포트가 한 쌍으로 존재한다. 특정 위치의 텔레포트를 들어가면 반대 쌍에 맞는 위치로 이동을 시켜주는데, 나가는 위치에 있는 텔레포트는 텔레포트 주변 빈 공간으로 이동을 시켜준다.
이 로직을 시전을 시키려면 텔레포트 오브젝트 각각에 특정 위치로 이동하라고 하는 반복적인 로직을 집어넣어 줄 수도 있었지만, 한가지의 코드로 모든 텔레포트의 기능을 통제 하고 싶어 개발을 했다.
RayCast는 물체의 중심으로 부터 특정 방향으로 특정 길이의 레이저를 쏴서 특정 방향 앞에 있는 물체를 탐지할 수 있게 구현이 돼있다.
나는 이 기능을 사용하여 빈 공간을 탐지를 하게 했다.
텔레포트 오브젝트는 3개의 면이 벽과 닿아 있고, 빈공간은 한 곳이기 때문에 4방향으로 레이저를 쏴서 벽이 탐지되지 않는 한 공간을 찾아 낸다.
찾아낸 공간에 플레이어를 이동 시키는 방식이다.
플레이 영상
쥬얼을 획득하고 포탈을 타며 깃발을 먹어 스테이지를 클리어 하는 미로게임이다.
다른 추가적인 퍼즐 요소가 생각 난다면 추가 해볼 생각입니다.