[WL-816d] 던전 NavMesh 를 콜라이더 기준으로 베이크(에러 100건 제거) + 한글 폰트 + 입구 위치 실측 반영 (#816)

- NavMeshSurface.useGeometry = PhysicsColliders — RenderMeshes 기본값은 메시 Read/Write 를 요구해 콘솔 에러 100건(실측)
- 베이크 후 앵커 위 NavMesh 존재를 로그로 남긴다(WL_Dungeon01 실측: (0,0.07,0) 있음)
- 이름표·「들어가기」 버튼에 한글 TMP 폰트 지정(기본 폰트에는 한글 글리프가 없어 □ 로 나왔다)
- 던전 3 입구를 덤불 위치에서 (2.5,0,11) 로 이동(에디트 모드 레이캐스트 실측)
- 던전 입장 시 프롬프트 숨김

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-09-13 12:47:45 +09:00
parent 6fa7a421d3
commit cac7889ec0
6 changed files with 49 additions and 10 deletions

View File

@ -74,7 +74,7 @@ MonoBehaviour:
sceneName: WL_Dungeon01
mapId: 903
stageIndex: 12
gatePosition: {x: -3, y: 0, z: 10.5}
gatePosition: {x: 2.5, y: 0, z: 11}
gateYaw: 180
gateScale: 1
gateColor: {r: 0.62, g: 0.42, b: 0.24, a: 1}

View File

@ -93,17 +93,25 @@ namespace WL.Island
// ─────────────────────────────────────────────────────────────────
static void BakeNavMesh(WLIslandSettings cfg, Scene scene)
{
var existing = Object.FindFirstObjectByType<NavMeshSurface>();
if (existing != null) { existing.BuildNavMesh(); NavBakes++; return; }
var go = new GameObject("~WL_DungeonNavMesh");
SceneManager.MoveGameObjectToScene(go, scene);
var surf = go.AddComponent<NavMeshSurface>();
// collectObjects = All · useGeometry = RenderMeshes 는 NavMeshSurface 기본값 그대로 쓴다
// (아레나 바닥에 콜라이더가 없어도 렌더 메시로 베이크된다 · 패키지 실측 NavMeshSurface.cs:54·66)
var surf = Object.FindFirstObjectByType<NavMeshSurface>();
if (surf == null)
{
var go = new GameObject("~WL_DungeonNavMesh");
SceneManager.MoveGameObjectToScene(go, scene);
surf = go.AddComponent<NavMeshSurface>();
}
// 🔴 기본값(RenderMeshes)은 메시마다 Read/Write 를 요구해 콘솔 에러 100건이 난다(실측).
// 콜라이더 기준으로 베이크하면 임포트 설정을 하나도 건드리지 않고 조용히 끝난다.
surf.useGeometry = UnityEngine.AI.NavMeshCollectGeometry.PhysicsColliders;
surf.BuildNavMesh();
NavBakes++;
WLIslandBridge.Log(cfg, "던전 NavMesh 런타임 베이크 완료");
UnityEngine.AI.NavMeshHit hit;
var def = StageDefOf(WLDungeonSceneSetup.Current);
Vector3 probe = def != null ? def.anchor : Vector3.zero;
bool onMesh = UnityEngine.AI.NavMesh.SamplePosition(probe, out hit, 6f, UnityEngine.AI.NavMesh.AllAreas);
WLIslandBridge.Log(cfg, "던전 NavMesh 런타임 베이크 완료 — 앵커 " + probe.ToString("F1") +
" 위 NavMesh " + (onMesh ? ("있음(" + hit.position.ToString("F2") + ")") : "🔴 없음"));
}
// ─────────────────────────────────────────────────────────────────

View File

@ -168,6 +168,7 @@ namespace WL.Island
if (cfg == null || d == null) return;
EnsureRunner();
WLIslandPrompt.Hide();
WLDungeonSceneSetup.Pending = d;
WLIslandSceneSetup.RestoreDuplicates();

View File

@ -339,6 +339,28 @@ namespace WL.Island
{
static readonly Dictionary<string, GameObject> s_cache = new Dictionary<string, GameObject>(4);
static TMPro.TMP_FontAsset s_font;
static bool s_fontTried;
/// <summary>이름표·버튼용 한글 폰트(없으면 null = TMP 기본 폰트).</summary>
public static TMPro.TMP_FontAsset Font(string path)
{
if (s_fontTried) return s_font;
s_fontTried = true;
if (string.IsNullOrEmpty(path)) return null;
#if UNITY_EDITOR
s_font = UnityEditor.AssetDatabase.LoadAssetAtPath<TMPro.TMP_FontAsset>(path);
if (s_font != null) return s_font;
#endif
try
{
var h = UnityEngine.AddressableAssets.Addressables.LoadAssetAsync<TMPro.TMP_FontAsset>(path);
s_font = h.WaitForCompletion();
}
catch (System.Exception) { s_font = null; }
return s_font;
}
public static GameObject LoadPrefab(string path)
{
if (string.IsNullOrEmpty(path)) return null;

View File

@ -160,6 +160,9 @@ namespace WL.Island
[Tooltip("입구 더미 기본 폭(m).")]
public float gateWidth = 2.4f;
[Tooltip("이름표·버튼에 쓸 TMP 폰트(한글 포함). 비우면 TMP 기본 폰트 — 기본 폰트에는 한글 글리프가 없어 □ 로 나온다.")]
public string fontAssetPath = "Assets/ThirdParty/TextMesh Pro/Addressables/Fonts & Materials/Font SDF.asset";
// ───────────────────────────────── 보상
[Header("보상 (던전 클리어 → 섬 코인)")]
[Tooltip("0 이면 보상을 주지 않는다.")]

View File

@ -53,11 +53,14 @@ namespace WL.Island
{
public static void Attach(Transform parent, Vector3 localPos, string text)
{
var cfg = WLIslandSettings.Instance;
var go = new GameObject("label");
go.transform.SetParent(parent, false);
go.transform.localPosition = localPos;
var tmp = go.AddComponent<TextMeshPro>();
var f = WLIslandAssets.Font(cfg != null ? cfg.fontAssetPath : null);
if (f != null) tmp.font = f;
tmp.text = text;
tmp.fontSize = 3.2f;
tmp.alignment = TextAlignmentOptions.Center;
@ -152,6 +155,8 @@ namespace WL.Island
trt.offsetMin = Vector2.zero; trt.offsetMax = Vector2.zero;
s_text = txtGo.AddComponent<TextMeshProUGUI>();
var pf = WLIslandAssets.Font(cfg != null ? cfg.fontAssetPath : null);
if (pf != null) s_text.font = pf;
s_text.fontSize = 44f;
s_text.alignment = TextAlignmentOptions.Center;
s_text.color = Color.white;