2016. 9. 22. 0:07
https://blog.naver.com/nagne2011/220817736388
-Unity : 출시도전 (가제)"레모의꿈" - 3 - 미니맵 기획(List)
가제가 바뀌었다 기존 판타지 캐러벤 상인 컨셉에서 리소스나 스토리상의 여러가지 타협점을 찾게되서 컨셉...
blog.naver.com
가제가 바뀌었다
기존 판타지 캐러벤 상인 컨셉에서
리소스나 스토리상의 여러가지 타협점을 찾게되서 컨셉이 변경되었다
바로 '네모'의 꿈이다
즉 플레이어나 모든 케릭터들이 네모로 나온다
...단순히 리소스가 부족하다는 이유 뿐만이 아니라
전투나 기타 요소를 간단하게 만들기 위해서이다.
기존의 공격력, 체력등의 스테이터스가 아니라
네모의 크기, 네모의 무게, 이동속도, 전투돌입 순서 등 단순하고 직관적인 스테이터스를 설정해서
더 많고 간단한 전투를 간단하게 진행해 나갈 수 있도록 했다.
게임컨셉도 개그물을 대폭 채용해서
모 커뮤니티 사이트의 설정대로 네모의 저주에 걸린 세계를 구하는 내용이다
(네모믜 저주 때문메 글자믜 미믐미 네모로만 써지게 되멌다) ...촘잠님?
리소스 문제가 해결되니까 작업은 빠르게 진행되었...으면 좋겠지만
추석과 아르바이트, 운동과 취업준비, 이력서 자기소개서 준비등의 이유로 조금씩 늦어지고있다...
대체 취업은 언제 되는거신가 ㅠㅠ
잡설은 끝,
오늘은 미니맵을 구현해봤다
일단 미니맵 컨셉은 아래와 같다
(좌측 메뉴는 상관없다)
격자 무늬의 탐험 가능한 지점이 표시되어있고
방문한 지역은 표시되지만 그 외 지역은 '전장의 안개'처럼 물음표로 가려져있고
플레이어 위치 (C)를 기준으로 가고자 하는 위치의 아이콘을 클릭하게 되면 그곳으로 거리에 비례한 시간에 따라 이동할 수 있다
이동하는 지점에는 아이콘으로 그 지점에 있는 오브젝트를 한눈에 볼 수 있고 마우스를 올려보면 해당 오브젝트에 대한 난이도 등을 볼 수 있다.
네모라는 컨셉에도 잘맞고 간단하면서도 임의의 지도라는 점을 매력적으로 표현할 수 있는 방법인데다가
자유도도 높게 설정되어있어서 마음에 딱 드는 지도모양이다
일단 완성된 스크린샷은 아래와 같다
컨셉스크린샷처럼 격자 무늬로 배치된 포인트 지점이 생성되고 포인트에 마우스를 올려두면 정보가 나오고,
클릭하면 이동거리를 계산하게 된다
포인트에 대한 위치정보는
좌측 상단을 기준으로, (0,0) 좌표로 매겨진다
그럼 코드를 살펴보자
이번 코드는 자료구조 List기능을 사용해서 만들 생각이다
왜냐하면 각 포인트가 각각 여러가지 정보를 가지게될것이고
필요하다면 그 내용을 xml등으로 저장할 수 있으려면 어디에 부속으로 딸린것보다
독립적으로 두는게 좋을것 같아서다
그리고 포인트의 오브젝트를 점령시 빈 오브젝트로 변경한다던지, 새로운 적이 출현한다던지 하는 변경점이 생길수도있고
새로 더 생기거나 비어버려서 없어질수 도있으니
생성과 삭제가 자유롭고 갯수의 제한이 적은 List구조가 어울릴것 같다
1
|
using System.Collections.Generic;
|
cs |
리스트(list)는 위 함수를 꼭 적어줘야한다 그래야 사용가능하다
우선 포인트 오브젝트들이 담길곳과 그걸 조절해줄 매니저를 만들어 주기 위해 빈 오브젝트를 생성하고 코드를 넣어줬다
그리고 관라지니까,
1
2
3
4
5
6
7
8
|
private static Test_worldMap sInstance;
public static Test_worldMap Instance
{
get
{
return sInstance;
}
}
|
cs |
를 사용하여 접근할 수 있도록 get함수를 만들어준다
1
|
public List<Test_mapPoint> mapPoints;
|
cs |
그다음 list를 선언해준다
List의 < > 괄호 안쪽에는 포인트 오브젝트가 가지고있는 Test_mapPoint라는 스크립트의 이름을 넣어준다
이렇게 하면 Test_mapPoint를 항목으로 하는 List가 만들어진다
1
2
3
4
5
6
7
8
9
10
11
12
|
public GameObject grid; //오브젝트들을 배열하기 위한 Grid스크립트가 있는 오브젝트
public GameObject poindPref; //포인트 오브잭트의 프리팹을 담을 변수
public int worldMapPointCount = 169; //포인트 갯수는 169개(13의 재곱)
public float worldMapPointCountSqrt = 0; //포인트 갯수의 제곱근. 좌표를 확인떄 사용한다
public GameObject playerObj; //플레이어 오브젝트
public GameObject clickPoint; //오브젝트 클릭시 클릭한 오브젝트가 담길 변수
public Camera Camera; //카메라
public int villageCount = 26; //마을 갯수는 몇개로 할껀가?
public int emptyCount = 8; //빈 곳의 갯수는?
|
cs |
일단 변수를 선언해준다.
오브젝트는 NGUI의 기능인 Grid를 이용하여 격자무늬로 배열 할것이고
갯수는 제곱의 숫자를 이용해서 정 사각형으로 구성할 생각이다
1
2
3
4
|
void Awake ()
{
sInstance = this;
}
|
cs |
get함수의 sInstance를 지정해주고 시작한다
1
2
3
|
worldMapPointCountSqrt = Mathf.Sqrt (worldMapPointCount);
int a = Mathf.FloorToInt (worldMapPointCountSqrt);
|
cs |
역시 Awake()함수에 들어간다
계산의 편의를 위해서 변수를 지정해준다
좌표를 잡으려면 포인트 오브젝트의 갯수인 169가 아니라,
그 제곱근, 즉 가로세로의 갯수인 13개가 필요하다
따라서 169의 제곱근을 구하기 위해서
Mathf.Sqrt() 함수를 이용하여 제곱근을 구해준다
이때, 가로세로 갯수를 담은 변수인 a는 int형이기 때문에
Mathf.Sqrt()함수를 통해 구한 제곱근을 Mathf.FloorToInt()함수를 통해서 int값으로 바꾸어준다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
for (int i = 0; i < worldMapPointCount; i++)
{
string str = string.Format ("Dot_({0}:{1})", i%a, i/a);
GameObject obj = Instantiate (poindPref, Vector3.zero, Quaternion.identity) as GameObject;
obj.name = str;
obj.transform.SetParent (grid.transform);
obj.transform.localScale = new Vector3 (1, 1, 1);
obj.GetComponent<Test_mapPoint> ().CurrentPointNum = i;
obj.GetComponent<Test_mapPoint> ().worldOption = 0;
//버튼
UIButton btn = obj.GetComponent<UIButton> ();
EventDelegate btnEvent = new EventDelegate ();
btnEvent.Set (this, "DistanceCheck");
btn.onClick.Add (btnEvent);
}
|
cs |
그리고 나서 오브젝트들을 생성한다
for (int i = 0; i < worldMapPointCount; i++)
생성갯수는 처음 선언한 대로 169개를 만들지만, 추후 변경 가능하도록 변수로 만들어둔다
string str = string.Format ("Dot_({0}:{1})", i%a, i/a);
그다음 아까 구해뒀던 제곱근(13)을 가지고 좌표대로 이름을 지어서 만들어준다
그리고 이제 Instantiate함수를 이용하여 포인트 오브젝트를 만든다
위치와 각도등을 초기화해서 만들어준뒤 이름을 부여하고
gameobject.transform.SetParent()함수를 이용해서 Grid의 하위로 보내줘서 Grid의 배치를 받게 한다
크기는 1.1.1로 맞춰준다
여기서 잠깐!
포인트 오브젝트인 pointPref의 구성 내용을 살펴보자!
프리팹으로 만들어둔 Dot의 구성내용은 아래와 같다
먼저 이미지Sprite함수가 있고
mapPoint함수를 넣어두었다
해당 함수는 해당 오브젝트의 포인트넘버, 좌표값 X,Y 그리고 맵속성을 int값으로 표시한다(0번은 적, 1번은 마을, 2번은 빈곳)
그리고 클릭 가능하도록 BoxColider와 UiButton함수를 넣어두었다
이제 다시 매니저 스크립트로 돌아가보자
아까 Awake()함수에서 오브젝트를 생성할때, Test_mapPoint의 속성값을 초기화 하고 번호를 할당해준다
해당 내용은 나중에 서술하겠다
마지막으로 포인트 오브젝트에 포함된 UIbutton함수들을 활성화 시켜서 EventDelegate()에 담아준다
1
2
3
4
5
6
7
8
9
10
11
12
13
|
for (int i = 0; i < emptyCount; i++)
{
int k = Random.Range (0, worldMapPointCount);
mapPoints [k].worldOption = 2;
}
for (int i = 0; i < villageCount; i++)
{
int k = Random.Range (0, worldMapPointCount);
mapPoints [k].worldOption = 1;
}
|
cs |
그다음 처음 변수로 설정한 숫자만큼
빈공간과 마을을 할당해 줘야한다
처음 만들때 169개 모두 적 위치인 0번으로 만들어주었으니
임의의 오브젝트중 설정한 숫자만큼은 1번 혹은 2번으로 만들어 주어야한다
아직 정확한 마을 비율을 만들지 않았으니 일단 확인 가능하도록 간단한 꼼수를 사용해서
갯수 표시를 해준다
1
2
3
4
5
6
7
8
9
10
11
12
|
int VC = 0;
int EC = 0;
for (int i = 0; i < mapPoints.Count; i++)
{
if (mapPoints [i].worldOption == 1)
VC++;
else if (mapPoints[i].worldOption == 2)
EC++;
}
Debug.Log (VC + " : " + EC);
|
cs |
이렇게 만들면 VC와 EC라는 변수에 숫자가 표시된다
그다음은 현재 위치와 클릭한 오브젝트와의 거리를 구하는 방법이다
임의의 오브젝트를 클릭했을때, 위 사진처럼 해당 위치와의 거리가 뜨도록 하는것이다.
먼저 DistanceCheck() 라는 함수를 만들어준다
이 함수는 오브젝트를 클릭했을때 불러 올 함수다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
void DistanceCheck()
{
//거리비교
int currentPlayerPositionPointX = Mathf.FloorToInt( playerObj.transform.localPosition.x) / 40;
int currentPlayerPositionPointY = Mathf.FloorToInt( playerObj.transform.localPosition.y) / 40;
RaycastHit hit;
Ray ray = Camera.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray.origin, ray.direction * 10, out hit))
{
clickPoint = hit.collider.gameObject;
}
int clickedPointX = Mathf.FloorToInt( clickPoint.transform.localPosition.x) / 40;
int clickedPointY = Mathf.FloorToInt( clickPoint.transform.localPosition.y) / 40;
int Xdistance = Mathf.Abs (currentPlayerPositionPointX - clickedPointX);
int Ydistance = Mathf.Abs (currentPlayerPositionPointY - clickedPointY);
int sumDistance = Xdistance + Ydistance;
Debug.Log (sumDistance);
}
|
cs |
먼저 현제 위치를 저장해준다음
Grid의 간격대로 40으로 나눠준다
이때 오브젝트의 transform.position의 값은 float이니까 int형으로 변환해주어야 한다
그리고 클릭된 오브젝트를 RayCast를 사용하여 확인해서 담아준뒤
그 포인트의 transform.position의 값을 담아준다
그다음이 중요하다
바로 X길이, Y길이를 구하는건데
Mathf.Abs()함수를 이용해서 두 값의 거리를 절대값으로 표기해준다
그리고 두 값을 합치면 총 거리가 나오게 되는것이다.
'유니티 > 실습' 카테고리의 다른 글
구글 할로윈 미니게임 - 0 (0) | 2022.02.14 |
---|---|
출시도전 - 러닝게임 - 9 - 출.시. (0) | 2022.02.14 |
출시도전 (가제)"산적왕" - 2 - 상점 기획 (0) | 2022.02.14 |
출시도전 (가제)"산적왕" - 1 - 마을 기획 (0) | 2022.02.14 |
출시도전 (가제)"산적왕" - 0 - 기획 (0) | 2022.02.14 |