RuleTile생성 -> 이름: RanTile-> 아래 사진과 같도록 설정
Rule Tile : 인접한 타일에 따라 이미지가 정해지는 타일
하지만 이걸 안쓰고 Random을 쓴다. 그렇기 때문에 다른 Rule Tile은 전혀 생성할 필요가 없음
Random값으로 주어진 타일디자인에는 의도적으로 Tile2가 가장 많이 나오도록 3/10 으로 설정했다
Window->2D->Tile Pallete창 열기
Hierarchy에서 다음과 같이 tilemap 생성
이후 Tilemap을 그려주면 된다
default brush에는 다양한 옵션이 있으니 참고. 예시엔 붓으로 Line brush로 20 x 20 틀을잡고 빈공간을 채우기 붓으로 채웠다
![]() |
![]() |
Ran Tile에서 노이즈를 조절할 수 있다
이제 만든 타일맵에서 벗어나도 재배치 하여 맵이 무한히 있는 것 처럼 구현한다
기본맵은 만든 타일맵 4개 활용. (40 X 40)
TileMap인스펙터에
TileMap Collider 컴포넌트 추가 -> 각 타일마다 콜라이더가 있는것을 하나의 큰 콜라이더로 합치기 위해
Composite Collider 2D 컴포넌트 추가 -> 이 컴포넌트를 사용한다는 것을 알리기 위해 TileMap Collider에 Used By Composite 체크 -> 그럼 is Trigger 와 같은 콜라이더 관리 속성이 Composite Collider 2D에 위임되고
캐릭터가 타일맵과 충돌하지 않기 위해 is Trigger 체크 -> Rigidbody2D의 BodyType을 sta
태그 설정
Add Tag -> Groud, Area태그 생성 후 TileMap 태그를 Ground로 설정
Player오브젝트 인스펙터에 추가하지 않고, 재배치하는 이벤트를 시행하는 오브젝트를 Player오브젝트의 자식으로 따로 둔다
Player선택 후 Empty GameObject 생성 (이름 : Area) -> Area태그 부여 -> 인스펙터 창에서 Box Collider 2D 컴포넌트 추가
-> 타일 맵의 크기가 20x20이었으니 Box Collider 의 size도 20 20 -> 마찬가지로 is Trigger 체크
두개의 스크립트 생성
1. Reposition 스크립트 2. GameManager(이름을 이렇게 하면 알아서 톱니바퀴 모양으로 아이콘을 바꿔주는데 아이콘만 다른 일반 스크립트다)
당연히 빈 오브젝트 만들고 GameManager넣고 TileMap에 Reposition 넣고
(*Reposition스크립트는 플레이어의 정보가 필요한데 Reposition스크립트에서 Player변수 만들고 사용하면 되긴 하지만
GameManager에서 관리하는게 좋다 그래서 GameManager에서 플레이어 정보를 Reposition에 전달한다)
하지만 이정도까지만 해선 이쁘게 관리할 수 없다 . 왜냐면 Reposition에서도 다시 GameManager 변수 만들고 그곳에 GameManager오브젝트 집어넣고.. 해야 하기 때문에
아예 GameManager를 메모리에 올려버린다 : Static으로 선언.
보통 이런경우 싱글톤을 써서 클래스 자체를 static화 하는게 맞는데 이 게임은 장면이 하나 밖에 없으므로 굳이 싱글톤을 쓸 필욘 없다
<GameManager.cs>
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Player player;
private void Awake()
{
Instance = this;
}
}
그러면 reposition에서 GameManager변수 만들고 인스펙터창에서 오브젝트 집어넣고 할 필요없이
GameManager.Instance.player
와 같이 바로 사용가능
재배치 로직
<Reposition.cs>
public class Reposition : MonoBehaviour
{
// Start is called before the first frame update
private void OnTriggerExit2D(Collider2D collision)
{
if (!collision.CompareTag("Area"))
return;
//플레이어의 position
Vector3 playerpos = GameManager.Instance.player.transform.position;
//이 오브젝트의 position
Vector3 myPos = transform.position;
//x축과 y축 거리 계산 => Math.Abs()함수를 사용해 절댓값으로
float diffX = Mathf.Abs(playerpos.x - myPos.x);
float diffY = Mathf.Abs(playerpos.y - myPos.y);
//플레이어 방향을 저장하기 위한 변수 추가
Vector3 playerDir = GameManager.Instance.player.inputVec;
//3항 연산자 사용 (조건) ? (true일때 값) : (false때 값)
//만약 normalized 가 없으면 굳이 이건 할 필욘 x
float dirX = playerDir.x < 0 ? -1 : 1;
float dirY = playerDir.y < 0 ? -1 : 1;
switch (transform.tag)
{
case "Ground":
if(diffX > diffY)
{
transform.Translate(Vector3.right * dirX * 40);
}
//이 조건에선 플레이어가 y축보다 x축으로 이동을 하고 있는 것이니 타일맵도 마찬가지로 x축으로 이동시켜준다
//Translate() : 지정된 값 만큼 현재위치에서 이동
//어느정도만큼 이동하겠다는 것이기 때문에 좌표가 아닌 이동할 양을 알려주는 것
//
//방향은 무조건 Vector3.
//Vector3.right에 마우스 올려놓으면 (1,0,0) 값 확인가능
//하지만 플레이어가 오른쪽뿐 아니라 왼쪽으로 갈 수 도 있기 때문에 아까 만든 dirX를 곱한다 (왼쪽이면 -1)
//타일맵 4개를 활용해 40X40사이즈이므로 *40
else if (diffX < diffY)
{
transform.Translate(Vector3.up * dirY * 40);
}
break;
case "Enemy":
break;
}
}
TileMap 이쁘게 배치하는 방법
설정 후 Gizmo이동 시 Ctrl + 기즈모드래그를 하면 10씩 이동함
카메라 설정
게임 윈도우를 모바일 화면 버전으로 보고 싶다면 왼쪽 위 게임 토글버튼(?)을 클릭하고 Simulator, 기종선택하면 가능
타일 사이에 흰줄이 보이는 픽셀 깨짐을 고치기 위해 카메라에 Pixel Perfect Camera 컴포넌트 추가(둘 중 urp 버전)
현재 사용하고 있는 에셋의 크기가 18이므로 Assets Pixel Per Unit 을 18로 설정
Pixel Perfect Camera 는 해상도가 짝수여야만 가능하다
Reference Resolution : 카메라 크기 계산을 위한 참고 해상도
이것을 x : 135 / y: 270으로 적당히 맞춘다
(캐릭터를 크게 보고 싶으면 이값을 좀 더키우고 작게 보고싶으면 줄이고)
(하지만 그 값은 타일맵 크기, Area크기, 재배치 거리는 카메라 크기와 비슷하게해야하기 때문에)
(타일맵 크기, Area크기, 재배치 거리 같이 맞춰줘야한다)
이제 카메라가 플레이어를 따라다니도록 해야한다. Main Camera를 다짜고짜 Player의 자식으로 넣어도 되기는 하지만 더 이쁘게 하기 위해 패키지를 설치하자
Window -> Package Manager -> Cinemachine 패키지 install -> Hierarchy에서 + 누르고 Cinemachine -> Virtual클릭 (이름 : VIrtual Camera)
이 오브젝트는 이미 있던 Main Camera를 감독하는 역할이다 (Main Camera는 감독을 받기 위한 Cinemachine Brain 컴포넌트 자동으로 생성)
Virtual Camera의 Cinemachine Virtual Camera 컴포넌트의 Follow속성에 Player오브젝트 Drag&Drop
게임실행을 해보면 카메라는 잘 따라다니지만 플레이어가 막 떨리면서 이동한다.. Update의 타이밍 때문이다.
Main Camera의 Cinemachine Brain 컴포를 보면 Update Method속성이 Update로 되어있다
우리는 물리 이동을 통해 움직이기 때문에 Update가 아닌 Fixed Update를 이용한다
그리고 현재 그림자 이미지가 안보인다. TileMap의 order in Layer때문이니까 모든 타일맵 선택 후 -1로 변경한다