지난번에 이어 게임을 만들어보자.
이번에 참고할 강의는 아래 강의이다.
https://www.youtube.com/watch?v=gIUVRYViG_g&list=PLctzObGsrjfyevwpeEVQ9pxGVwZtS7gZK&index=9
이번 강의부터 한동안은 맵 자동 생성에 대해 다룬다.
시작해보자.
맵 생성기를 제작하여 임시로 저장해 놓을 새로운 씬 MapGenerator 를 만든다.
빈 오브젝트 Map 을 생성하고 위치를 0, 0, 0 으로 설정하자.
MapGenerator 스크립트를 생성하고 Map 오브젝트에 할당해준다.
이제 MapGenerator 스크립트를 작성하자, 일단은 일부만 작성했다.
| MapGenerator 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
public Transform tilePrefab; // 인스턴스화 할 타일 프리팹
public Vector2 mapSize; // 맵 크기
[Range(0, 1)] // 범위 지정
public float outlinePercent; // 테두리 두께
void Start()
{
GeneratorMap();
}
public void GeneratorMap() {
for(int x = 0; x < mapSize.x; x++)
{
for(int y = 0; y < mapSize.y; y++) // 지정한 맵 크기만큼 루프
{
Vector3 tilePosition = new Vector3(-mapSize.x / 2 + 0.5f + x, 0, -mapSize.y/2 + 0.5f + y);
/* 타일이 생성될 위치 저장.
-지정한 맵 가로 길이/2 를 설정하면 0에서 가로길이의 절반만큼 왼쪽으로 이동한 위치가 된다.
이를 활용하여 z 좌표에도 적용해 화면의 왼쪽 위 모서리부터 맵이 생성되도록 한다. */
Transform newTile = Instantiate(tilePrefab, tilePosition, Quaternion.Euler(Vector3.right * 90)) as Transform;
/* 타일을 인스턴스화 하여 생성하고 위치, 각도를 설정
위치는 위에서 생성한 값을 전달하고 각도는 Quaternion(사원수) 메소드를 사용,
오일러 각을 기준으로 회전시킨다. */
newTile.localScale = Vector3.one * (1 - outlinePercent);
/* localScale 은 오브젝트의 상대적 크기, Vector3.one 은 Vector3(1,1,1) 이다.
크기를 지정한 테두리 두께만큼 줄여서 지정한다. */
}
}
}
}
위 스크립트에서 사용할 오브젝트, 프리팹을 준비하자.
먼저 Quad 오브젝트 Tile 을 생성한다.
메시 콜라이더를 제거해주고 X 회전값을 90으로 설정해 눕힌다.
이제 Prefabs 폴더로 이동해 프리팹으로 만들고,
이 프리팹을 Map 오브젝트 MapGenerator 스크립트의 tilePrefab 에 할당한다.
맵 크기는 10 X 10 으로 설정해주자.
위 스크립트에서 타일을 생성 후 위치를 지정할 때 회전값에서 사원수와 오일러 각을 사용한다.
쉽게 생각해 transform.rotation 에 적용하기 위한 변수라고 생각하자.
(설명은 아래 링크 참고)
https://docs.unity3d.com/kr/2018.4/Manual/QuaternionAndEulerRotationsInUnity.html
이제 잠시 실행해보자. (테두리는 0.1 정도로 설정했다)
타일 맵이 잘 생성된 것을 볼 수 있다.
이제 여러 기능도 추가해야 하는데, 매번 추가하고 실행하기가 꽤 번거롭다..
이를 위해 에디터 스크립트를 만들어 변경할 때 마다 갱신하도록 해보자.
먼저 에디터를 저장할 폴더를 생성한다.
에디터는 반드시 Editor 폴더에 저장되어야 한다.
에디터 실행 시 일단 먼저 할 일은 생성되어있는 타일들을 제거하는 것이다.
이를 위해 타일들을 자식으로 가지고 있을 부모 오브젝트를 만들고,
타일 생성 전에 이미 있는 타일들을 제거하고 다시 생성하도록 MapGenerator 스크립트를 수정하자.
| MapGenerator 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapGenerator : MonoBehaviour
{
public Transform tilePrefab; // 인스턴스화 할 타일 프리팹
public Vector2 mapSize; // 맵 크기
[Range(0, 1)] // 범위 지정
public float outlinePercent; // 테두리 두께
void Start()
{
GeneratorMap();
}
public void GeneratorMap() {
string holderName = "Generator Map"; // 타일 오브젝트를 가질 부모 오브젝트 이름
if(transform.Find(holderName)) // 위 오브젝트에 자식 오브젝트가 있다면
// * 강의에서는 FindChild 를 사용하는데, 버전이 바뀌면서 사용하지 않고 Find 로 변경되었다.
{
DestroyImmediate(transform.Find(holderName).gameObject);
/* 오브젝트의 자식 게임 오브젝트를 제거한다.
에디터에서 호출 할 것이기 때문에 DestroyImmediate 를 사용한다. */
}
Transform mapHolder = new GameObject(holderName).transform;
// 타일을 자식 오브젝트로 가질 새 오브젝트를 생성
mapHolder.parent = transform;
// 현재 오브젝트를 mapHolder 오브젝트의 부모 오브젝트로 설정.
for(int x = 0; x < mapSize.x; x++)
{
for(int y = 0; y < mapSize.y; y++) // 지정한 맵 크기만큼 루프
{
Vector3 tilePosition = new Vector3(-mapSize.x / 2 + 0.5f + x, 0, -mapSize.y/2 + 0.5f + y);
/* 타일이 생성될 위치 저장.
-지정한 맵 가로 길이/2 를 설정하면 0에서 가로길이의 절반만큼 왼쪽으로 이동한 위치가 된다.
이를 활용하여 z 좌표에도 적용해 화면의 왼쪽 위 모서리부터 맵이 생성되도록 한다. */
Transform newTile = Instantiate(tilePrefab, tilePosition, Quaternion.Euler(Vector3.right * 90)) as Transform;
/* 타일을 인스턴스화 하여 생성하고 위치, 각도를 설정
위치는 위에서 생성한 값을 전달하고 각도는 Quaternion(사원수) 메소드를 사용,
오일러 각을 기준으로 회전시킨다. */
newTile.localScale = Vector3.one * (1 - outlinePercent);
/* localScale 은 오브젝트의 상대적 크기, Vector3.one 은 Vector3(1,1,1) 이다.
크기를 지정한 테두리 두께만큼 줄여서 지정한다. */
newTile.parent = mapHolder;
// 타일의 부모 오브젝트 설정
}
}
}
}
에디터 폴더에 MapEditor 스크립트를 생성한다.
이제 MapEditor 스크립트를 작성하자.
| MapEditor 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor; // 유니티 에디터 사용
[CustomEditor(typeof(MapGenerator))]
// 에디터가 사용(설정)할 클래스 명시
public class MapEditor : Editor { // 에디터 상속
public override void OnInspectorGUI() // 인스펙터 메소드
{
base.OnInspectorGUI(); // 우리가 유니티에서 사용하는 기본 인스펙터의 구성물들을 포함시킨다.
MapGenerator map = target as MapGenerator;
/* 유니티에서 위에 CuntomEditor 로 명시해둔 클래스를 target 으로 지정해준다.
이를 형변환하여 MapGenerator map 으로 가져오자. */
map.GeneratorMap();
/* GUI 가 그려지는 매 프레임, 즉 GUI 에서 우리가 값을 설정하며 바꿀때마다
메소드를 호출하여 타일을 재생성한다. */
}
}
이제 프로젝트에서 오브젝트의 인스펙터를 통해 타일의 생성을 위한 값들을 조정하면
타일맵이 실시간으로 변경되는 모습을 볼 수 있다.
다음 강의에서 다른 기능들을 더 추가해보자.
'Unity > 게임개발' 카테고리의 다른 글
[Unity] 게임 개발 일지 | 탑다운 슈팅 10 (1) | 2023.11.30 |
---|---|
[Unity] 게임 개발 일지 | 탑다운 슈팅 9 (0) | 2023.11.29 |
[Unity] 게임 개발 일지 | 탑다운 슈팅 7 (0) | 2023.11.29 |
[Unity] 게임 개발 일지 | 탑다운 슈팅 6 (0) | 2023.11.24 |
[Unity] 게임 개발 일지 | 탑다운 슈팅 5 (1) | 2023.11.23 |