▪️MiniMap 카메라 Clamp/플레이어 추적 & 버그 디버깅 TIL
📑 목차
⓵ 트러블슈팅
𝟙 문제 상황 & 요약
𝟚 원인 분석
- Clamp/Tilemap/Camera Tracking
𝟛 해결 과정
- Clamp Setting 위치에 따른 결과 차이
- 후속 테스트
𝟜 결과
𝟝 다음 계획
🗂️ Minimap Animaion 트러블슈팅
① 문제 상황 & 증상 요약
- 미니맵 카메라가 플레이어를 따라가지 않거나, 이동이 부자연스러움
- 방 입장/이동 시만 Clamp(카메라 이동 제한)가 적용되고,
방 내부에서는 플레이어를 따라오지 않음 - 플레이어 아이콘이 방 내부에서 제대로 보이지 않기도 함
-> 사이즈 조정해도 해결 안됨 - Clamp(min, max) 값이 너무 빡빡하거나 0,0~0,0 등 비정상일 때,
카메라가 고정되어 움직이지 않음
② 원인 분석 - Clamp / Tilemap / Camera Tracking
▪️현재 구조에서는
- Clamp(min/max)는 방 입장 시 에만 갱신
- target(플레이어)는 한번 세팅하면 계속 따라가야 함
- LateUpdate에서 "매 프레임" 플레이어의 위치를 읽어서 부드럽게 따라가게 되어 있음
▪️만약
- 방 이동 시에만 카메라가 움직이고, 방 안에서 머무를 때는 플레이어를 따라오지 않는다면?
▪️원인
- 아마도 LateUpdate에서 target이 null이거나
- SetTarget이 방 입장 시에만 한번 호출되고,
LateUpdate에서 실제로 따라가는 코드를 생략했거나 - 혹은 Clamp min/max가 너무 빡빡하게 잡혀있어서 카메라가 아예 움직이지 않을 수 있음
▪️그렇다면 Clamp 값이 정해지는 규칙은 ?
- Clamp 값(min, max)은 타일맵(방)의 경계를 기준으로 설정됨
▫️예시
방의 타일맵 bounds가 min(10, 10), max(20, 20)이라면
_clampMin = (10, 10)
_clampMax = (20, 20)
-> 단, 방의 크기가 작으면 카메라가 움직일 수 있는 공간이 거의 없음!
- 방 타일맵 bounds가 실제로 너무 작은 경우 (예: 10,10 ~ 12,12)
-> 카메라 이동 제한이 너무 심하게 적용됨 (min==max에 가깝거나, 카메라 오프셋 등)
- 플레이어가 아무리 움직여도, 카메라의 Clamp 범위(=min~max)가
플레이어 움직임 범위를 다 감싸지 못하면 카메라가 거의 안 움직이거나, 한 위치에 고정된 것처럼 보임 - Clamp 값을 늘린다고 카메라가 잘 따라오는 것은 아님
-> 따라서, Clamp 범위가 실제로 플레이어 이동 범위보다 충분히 넓어야 한다!
▪️체크리스트
- 타일맵 bounds(min/max) 값이 실제 플레이어 이동 범위와 맞는가?
- target(플레이어)의 position이 충분히 변하고 있는가?
- MiniMapCamera의 LateUpdate가 정상적으로 실행되고 있는가?
- Clamp/Lerp가 정상 적용 중인지 Debug로 값 확인 필요
③ 해결 과정
▪️우선, 카메라가 움직이게끔 수정하자!
기존 코드
- 임시 플레이어와 적을 prefab화 해서 사용함
public void DrawRoom(GameObject tempPlayer, Tilemap roomTilemap, GameObject[] tempEnemies)
{
SetPlayer(tempPlayer.transform);
if (tempEnemies != null)
{
var enemyList = new List<Transform>();
foreach (var e in tempEnemies)
if (e != null) enemyList.Add(e.transform);
SetEnemies(enemyList);
}
if (roomTilemap != null)
{
CalculateMapBounds(roomTilemap);
}
}
- 입력값:
- GameObject 타입의 플레이어, 적 오브젝트
- Tilemap 타입의 맵 정보
- 동작:
- SetPlayer/SetEnemies로 Transform만 따로 빼서 관리
- roomTilemap이 있으면 CalculateMapBounds(roomTilemap) 호출(맵의 경계 계산?)
- 전체적으로:
- “플레이어, 적, 맵” 정보를 받아서 미니맵에 필요한 정보로 변환(Transform, Bounds 등)
- 적/플레이어는 GameObject로 입력받고 내부에서 Transform으로 바꿔줌
- 맵 사이즈/위치 계산은 RoomManager에서 담당
개선 코드
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Tilemaps;
using System.Collections.Generic;
public class MiniMapUI : BaseUI
{
[SerializeField] private RawImage _minimapRawImage;
[SerializeField] private GameObject player;
[SerializeField] private Tilemap currentRoomTilemap;
public override int CanvasLayer => 0;
private Transform _player;
private RectTransform _miniMapRectTransform;
private Vector2 _worldMin;
private Vector2 _worldMax;
private MiniMapCamera _minimapCamera;
private void Start()
{
_minimapCamera = FindObjectOfType<MiniMapCamera>();
}
public void SetPlayer(Transform player)
{
_player = player;
if (_minimapCamera != null)
_minimapCamera.SetTarget(player);
}
public void DrawRoom(Tilemap roomTilemap, Transform player)
{
if (roomTilemap == null || player == null) return;
BoundsInt bounds = roomTilemap.cellBounds;
Vector3Int minInt = bounds.min;
Vector3Int maxInt = bounds.max;
Vector2 min = new Vector2(minInt.x, minInt.y);
Vector2 max = new Vector2(maxInt.x, maxInt.y);
SetPlayer(player);
if (_minimapCamera != null)
_minimapCamera.SetClampBounds(min, max);
if (_minimapRawImage != null)
{
_miniMapRectTransform = _minimapRawImage.rectTransform;
AdjustMiniMapSize(bounds.size);
}
_worldMin = min;
_worldMax = max;
}
public void LocateMiniMapCamera(Vector3 position)
{
if (_minimapCamera != null)
_minimapCamera.MoveTo(position);
}
private void AdjustMiniMapSize(Vector3Int tilemapSize)
{
float scaleFactor = 10f;
_miniMapRectTransform.sizeDelta = new Vector2(tilemapSize.x, tilemapSize.y) * scaleFactor;
}
private void Update()
{
if (_miniMapRectTransform == null) return;
}
private Vector2 WorldToMiniMap(Vector3 worldPos)
{
float x = (worldPos.x - _worldMin.x) / (_worldMax.x - _worldMin.x) * _miniMapRectTransform.sizeDelta.x;
float y = (worldPos.y - _worldMin.y) / (_worldMax.y - _worldMin.y) * _miniMapRectTransform.sizeDelta.y;
return new Vector2(x, y);
}
public override void Enable() => gameObject.SetActive(true);
public override void Disable() => gameObject.SetActive(false);
}
- 입력값:
- Tilemap 타입의 맵 정보
- Transform 타입의 플레이어 (GameObject → Transform 아님, 바로 Transform)
- 동작:
- 맵의 cellBounds로 미니맵 영역 계산 (BoundsInt → min, max로 벡터화)
- MiniMapCamera의 클램프 영역을 직접 세팅
- RawImage 크기를 맵 사이즈에 맞게 동적으로 조정
- 내부적으로 _worldMin, _worldMax 저장
- 전체적으로:
- 미니맵 카메라와 RawImage(미니맵 UI)의 크기, 영역, 플레이어 위치 동기화까지 포함
- 더 직관적이고 직접적으로 미니맵 UI 영역을 조정하는 기능 추가
차이점
| 입력 데이터 | GameObject(플레이어, 적) | Transform(플레이어), Tilemap(맵) |
| 플레이어/적 처리 | GameObject로 받고 Transform 추출 | Transform으로 바로 받음(더 단순) |
| 맵 처리 | CalculateMapBounds(함수 분리) | bounds/cellBounds로 직접 계산 |
| 미니맵 UI 크기 | 별도 없음(기본값/고정?) | AdjustMiniMapSize로 동적 조정 |
| 카메라 영역 | 없음(함수에 미포함) | _minimapCamera.SetClampBounds로 동기화 |
| RawImage/UI와 연결 | 직접적 UI 제어 없음 | RawImage/RectTransform을 직접 조정 |
| 내부 State | worldMin/worldMax 등 분리 관리 | DrawRoom에서 한 번에 처리(직접 연결) |
| 기타 | 적 관리 포함(SetEnemies) | 적 미포함(플레이어, 맵 중심) |
즉, 개선된 코드가
- 미니맵 UI/카메라/경계 조정까지 DrawRoom에서 한 번에 처리
-> 더 직관적이고 UI 자동화에 가까움
- 입력값이 Transform/Tilemap 중심으로 단순화돼서,
-> 더 간단하게 함수 호출, 유지보수 쉬움
결과적으로,
방 이동시에는 카메라가 움직이니 플레이어 부분을 수정해보자.
문제 코드
public void DrawRoom(Tilemap roomTilemap, Transform player)
{
// ...
SetPlayer(player);
if (_minimapCamera != null)
_minimapCamera.SetClampBounds(min, max);
}
- DrawRoom(방 입장 시)에서만 Clamp가 갱신됨
-> 방 이동(씬 이동) 때만 카메라가 움직이고, 방 안에서는 플레이어를 따라가지 않음
개선 코드
private void Start() {
_minimapCamera = FindObjectOfType<MiniMapCamera>();
// 전체 Clamp를 Start에서 먼저 세팅
float clampPadding = 1.0f;
Vector2 paddedMin = new Vector2(mapMin.x + clampPadding, mapMin.y + clampPadding);
Vector2 paddedMax = new Vector2(mapMax.x - clampPadding, mapMax.y - clampPadding);
if (_minimapCamera != null)
_minimapCamera.SetClampBounds(paddedMin, paddedMax);
if (player != null && _minimapCamera != null)
_minimapCamera.SetTarget(player.transform);
}
- Start()에서 전체 맵 기준으로 Clamp를 여유있게 지정해 플레이어를 항상 부드럽게 따라가도록 개선
- DrawRoom에서는 필요할 때만 방 경계로 Clamp 갱신
▪️Clamp 세팅 위치에 따른 결과 차이
| DrawRoom() | 방 입장 기준 / 이동 시에만 갱신 | 방 내부에서 카메라 거의 안 움직임 (범위 너무 좁으면 아예 고정) |
| Start() | 맵 전체 기준 / Clamp값 여유 있게 지정 | 항상 플레이어를 따라감, 버벅임/고정 현상 해결 |
-> 즉, Start에서 Clamp를 먼저 넓게 잡으면, 타일맵 없이도(혹은 DrawRoom 호출 없이도)
항상 플레이어 이동에 맞춰 카메라가 정상적으로 따라옴
반대로, DrawRoom에서만 Clamp 갱신하면 방 범위가 너무 작으면 카메라 이동 공간 자체가 없음
첫번째 코드
미니맵 관련 테스트용
public void GenerateMiniMapTexture(Tilemap tilemap)
{
var bounds = tilemap.cellBounds;
Texture2D minimapTexture = new Texture2D(bounds.size.x, bounds.size.y);
for (int x = 0; x < bounds.size.x; x++)
{
for (int y = 0; y < bounds.size.y; y++)
{
Vector3Int cellPosition = new Vector3Int(bounds.x + x, bounds.y + y, 0);
TileBase tile = tilemap.GetTile(cellPosition);
if (tile != null)
{
minimapTexture.SetPixel(x, y, Color.white); // 타일마다 색을 다르게 하고 싶다면 조건 추가
}
else
{
minimapTexture.SetPixel(x, y, Color.clear);
}
}
}
minimapTexture.Apply();
_minimapRawImage.texture = minimapTexture;
}
- Clamp 범위(카메라 이동 제한 경계)를
DrawRoom(타일맵을 기반으로 하는 함수)에서만 세팅하고 있음. - Start()에서 Clamp 경계를 지정하는 코드가 없음.
- 즉, 방 진입/타일맵 기준이 아닌 경우(씬 시작, 전체 맵 등)에는
카메라 Clamp 값이 0,0~0,0 상태로 남아있을 수 있음
→ 카메라가 움직이지 않음.
두 번째 코드
using System;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Tilemaps;
using System.Collections.Generic;
public class MiniMapUI : BaseUI
{
[SerializeField] private RawImage _minimapRawImage;
[SerializeField] private GameObject player;
[SerializeField] private Tilemap currentRoomTilemap;
[SerializeField] private Vector2 mapMin = new Vector2(-30, -30);
[SerializeField] private Vector2 mapMax = new Vector2(30, 30);
[SerializeField] private float clampPadding = 1.0f;
public override int CanvasLayer => 0;
private Transform _player;
private RectTransform _miniMapRectTransform;
private Vector2 _worldMin;
private Vector2 _worldMax;
private MiniMapCamera _minimapCamera;
private void Start()
{
_minimapCamera = FindObjectOfType<MiniMapCamera>();
if (player != null && _minimapCamera != null)
_minimapCamera.SetTarget(player.transform);
float clampPadding = 1.0f;
Vector2 paddedMin = new Vector2(mapMin.x + clampPadding, mapMin.y + clampPadding);
Vector2 paddedMax = new Vector2(mapMax.x - clampPadding, mapMax.y - clampPadding);
if (_minimapCamera != null)
_minimapCamera.SetClampBounds(paddedMin, paddedMax);
}
public void SetPlayer(Transform player)
{
_player = player;
if (_minimapCamera != null)
_minimapCamera.SetTarget(player);
}
public void DrawRoom(Tilemap roomTilemap, Transform player)
{
if (roomTilemap == null || player == null) return;
BoundsInt bounds = roomTilemap.cellBounds;
Vector3Int minInt = bounds.min;
Vector3Int maxInt = bounds.max;
Vector2 min = new Vector2(minInt.x, minInt.y);
Vector2 max = new Vector2(maxInt.x, maxInt.y);
SetPlayer(player);
if (_minimapCamera != null)
_minimapCamera.SetClampBounds(min, max);
if (_minimapRawImage != null)
{
_miniMapRectTransform = _minimapRawImage.rectTransform;
AdjustMiniMapSize(bounds.size);
}
_worldMin = min;
_worldMax = max;
}
public void LocateMiniMapCamera(Vector3 position)
{
if (_minimapCamera != null)
_minimapCamera.MoveTo(position);
}
private void AdjustMiniMapSize(Vector3Int tilemapSize)
{
float scaleFactor = 10f;
_miniMapRectTransform.sizeDelta = new Vector2(tilemapSize.x, tilemapSize.y) * scaleFactor;
}
private void Update()
{
if (_miniMapRectTransform == null) return;
}
private Vector2 WorldToMiniMap(Vector3 worldPos)
{
float x = (worldPos.x - _worldMin.x) / (_worldMax.x - _worldMin.x) * _miniMapRectTransform.sizeDelta.x;
float y = (worldPos.y - _worldMin.y) / (_worldMax.y - _worldMin.y) * _miniMapRectTransform.sizeDelta.y;
return new Vector2(x, y);
}
public override void Enable() => gameObject.SetActive(true);
public override void Disable() => gameObject.SetActive(false);
}
- Start()에서
- mapMin, mapMax를 인스펙터에서 미리 넓게 지정
- 여기에 clampPadding을 더해서 넉넉한 Clamp 범위를 만들어
바로 미니맵 카메라에 전달!
- 즉, 방 입장과 상관없이 항상 넓은 Clamp가 적용
→ 플레이어가 움직일 때마다 카메라가 정상적으로 따라감.
해결!
해결방법
- 두 번째 코드에서는 Start()에서 바로 Clamp 세팅
(SetClampBounds(paddedMin, paddedMax);) - 즉, 타일맵이 없어도(혹은 DrawRoom 호출 없이도)
초기값이 무조건 넉넉하게 잡혀서 카메라가 따라다님! - (DrawRoom을 사용하면 방마다 Clamp를 바꿀 수도 있고,
Start에서 한 번만 세팅하면 맵 전체 Clamp로 항상 플레이어를 따라다님)
요약
- 첫 번째: Clamp가 초기화 안 됨 → 카메라 안 움직임
- 두 번째: Clamp가 Start에서 항상 넓게 초기화 → 플레이어 이동에 따라 카메라 정상 추적
미니맵 통로에서 플레이어가 지나갈 때 플레이어 보이지 않게
방법
입구에 알 수 있게끔 (콜라이더 / -> 미니맵 종료 | 재시작
혹은 카메라 위치 범위를 주어 | 플레이어 위치가 어디~ 범위라면
수정 전 -> 수정 후



플레이어 위치에 따라 미니맵에도 clamp animaion이 적용되는 모습을 확인할 수 있다.