Unity 2D 프로젝트에서 Tilemap과 Tilemap Collider 2D를 이용해 맵 충돌 영역을 구성하는 경우,
에디터에서는 충돌이 정상적으로 동작하지만,
빌드 후 실행 파일에서 플레이해 보면 일부 타일의 충돌이 사라지는 현상이 발생할 수 있다.
에디터 모드에서는 타일의 Sprite가 정상적으로 보이고, 충돌 판정 또한 잘 작동한다.
그러나 빌드된 환경에서는 해당 타일들이 시각적으로는 존재하더라도 Tilemap Collider 2D가 생성되지 않거나 일부 영역이 비어 있는 문제가 발생한다.
이 문제는 타일에 연결된 Sprite Asset이 빌드에 포함되지 않은 경우 발생한다.
Unity의 타일맵 시스템은 타일 데이터를 기반으로 콜라이더를 생성하는데,
이때 타일의 Sprite가 참조되지 않으면 빌드 시 해당 Sprite가 Unused Asset으로 인식되어 제외될 수 있다.
특히 다음과 같은 경우에 자주 발생한다.
Sprite가 프로젝트 내에 존재하지만, 직접적으로 Scene이나 Prefab에서 참조하지 않는 경우
(Tile Palette에서만 사용되고, 코드나 프리팹에서 Sprite를 직접 참조하지 않음.)
Tile Asset이 ScriptableObject 형태로 존재하지만, 해당 Sprite 필드가 에디터 상에서만 유효
( 일부 커스텀 Tile 클래스에서 #if UNITY_EDITOR로 Sprite를 에디터 전용으로만 관리하는 경우)
Addressables 또는 AssetBundle을 사용하지 않고, 기본 빌드 파이프라인만 사용하는 경우
( Unity의 빌드 프로세스는 사용하지 않는 Sprite를 자동으로 스트리핑(제거)한다. )
빌드 후에는 Tilemap Collider가 타일의 Sprite 정보를 참조하여 콜라이더를 만들지만, Sprite가 빠져있으므로 해당 타일을 무시하게 된다.
그 결과 충돌이 사라지는 것처럼 보인다.
이 문제를 간단히 재현하려면 다음과 같은 단계를 거친다.
Tilemap 생성
Tile Palette를 통해 임의의 Sprite로 Tile을 만들어 배치
Tilemap에 Tilemap Collider 2D를 부착
Sprite가 프로젝트에서 다른 곳에서는 전혀 참조되지 않도록 둔다
빌드 후 실행
결과적으로, 해당 Sprite 기반의 타일은 빌드 시 Asset이 포함되지 않아 Collider가 생성되지 않는다.
해당 Sprite를 Assets/Resources 폴더 아래에 넣으면, Unity는 이를 빌드 시 무조건 포함한다.
장점: 구현이 간단하며, 자동으로 빌드에 포함
단점: Resources 폴더에 있는 모든 Asset이 빌드에 포함되므로, 불필요한 용량 증가 가능성 있음
타일 Sprite를 Addressable Asset으로 등록하고, 빌드 시 포함하도록 한다.
장점: 필요한 리소스만 효율적으로 관리 가능
단점: Addressables 셋업 과정 필요
빌드에서 스트리핑되지 않도록, 임의의 Script나 ScriptableObject에 Sprite를 필드로 참조시킨다.
해당 Script를 씬의 빈 GameObject에 붙여서 Sprite를 드래그해 두면, Unity 빌드 파이프라인에서 사용 중인 리소스로 인식한다.
빌드 전에 타일맵에 사용된 Sprite 목록을 추출하여 빌드 인클루드 리스트에 추가하는 방법이다.
IPreprocessBuildWithReport를 구현하여 빌드 직전에 Sprite 참조를 강제로 등록할 수 있다.
이 문제는 Unity 빌드 파이프라인의 Unused Asset 제거 로직과 타일맵의 Sprite 기반 콜라이더 생성 로직이 맞물리면서 발생한다.
따라서 빌드 시 Sprite가 제거되지 않도록 참조를 유지하는 것이 핵심이다.
추천 접근 순서
간단한 프로젝트 → 방법 1(Resources) 또는 방법 3(직접 참조)
대규모 프로젝트 → 방법 2(Addressables) 또는 방법 4(빌드 스크립트)