[WL-814r] 시범 전투장 Play 에러 제거 + 데모 카메라 이식 + 이동 리그 (#814)

- PC_LH_M05 씬 인스턴스에서 게임 컴포넌트 7종 제거(WizardActor·NavMeshAgent·
  Rigidbody·CapsuleCollider·SkinnedMeshAfterImage·WLPcScaleCompensator·
  WLWeaponFitter) → 게임 초기화 없이 Update 가 돌며 터지던
  KeyNotFoundException: 'Freeze'(Actor.cs:1065) 제거. 프리팹 수정 0.
  루트 스케일 1.05266 · 몸 높이 1.21651 m 는 제거 전후 델타 0 실측.
- Main Camera 를 Demo.unity 실측값으로 이식: 직교 size 10 · euler(30,60,0)
  · near 0.3 / far 500 · clear Skybox · depth -1 · HDR/MSAA on
  + UniversalAdditionalCameraData(post off · AA none · rendererIndex -1).
- 씬 라이트 3개에 UniversalAdditionalLightData 추가(데모와 동일 구성).
- Terrain.drawTreesAndFoliage false→true(데모와 동일).
- ArenaWalker.cs(신규 · 씬 전용): WASD 이동 + 방향 회전 + idle/run 상태 재생
  + 카메라 추적 + Terrain.SampleHeight 접지. 속도 3.9 / 회전 300 은
  LH_M05.prefab NavMeshAgent 실측값.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
깃 관리자 2026-09-12 21:52:53 +09:00
parent 979eb53d2a
commit 4f2fdb0a86
3 changed files with 333 additions and 6 deletions

View File

@ -0,0 +1,126 @@
// ─────────────────────────────────────────────────────────────────────────────
// ArenaWalker.cs — 시범 전투장(WL_ArenaProto) 전용 이동 리그 (발주서 WL-814r · PD 「걸어다니며 크기 감 잡기」)
//
// ■ 왜 새 스크립트인가
// 이 씬의 캐릭터는 **전시용**이라 게임 컴포넌트(`WizardActor`·`NavMeshAgent`·`Rigidbody`·`CapsuleCollider`)를
// 전부 떼어 냈다(814r §1 · 그것들이 게임 초기화 없이 돌면서 `KeyNotFoundException: 'Freeze'` 가 프레임마다 터졌다).
// 되살리면 에러 0 이 깨지므로, **본편 시스템을 전혀 건드리지 않는 씬 전용 리그**를 따로 둔다.
//
// ■ 캐릭터에 붙이지 않고 별도 오브젝트에 두는 이유
// `PC_LH_M05` 는 프리팹 인스턴스다. 거기에 컴포넌트를 더하면 「전시용 = Transform·Animator·렌더러뿐」이라는
// 814r §1 의 완료 조건이 흐려진다. 그래서 이 리그가 밖에서 `body` 를 움직인다(프리팹 수정 0 · 인스턴스 추가 0).
//
// ■ 실측해서 가져온 값 (하드코딩 아님 · 전부 인스펙터 노출 · 출처 주석)
// · moveSpeed 3.9 = `Assets/Res_Addr/PC/LH_M05.prefab` NavMeshAgent `m_Speed` (인게임 이동 속도 그대로)
// · turnSpeed 300 = 같은 프리팹 NavMeshAgent `m_AngularSpeed`
// · 애니메이션 전환 = 원본 `Actor.AnimationPlay()` 가 쓰는 **상태 이름 직접 재생** 방식 그대로
// (`Assets/Script/Character/Actor.cs:2031` `m_animation.Play(aniname)` · 이름은 `MyValue.cs:72`
// `eAnim.Idle→"idle"` / `eAnim.Run→"run"` · `pcanim_mage.controller` 에 두 상태 모두 존재 실측).
// 🔴 이 컨트롤러의 Base Layer 에는 idle/run 으로 들어가는 **트랜지션이 없다** — 파라미터로는 못 바꾼다.
//
// ■ 바닥
// 콜라이더를 전부 뗐으므로 물리를 쓰지 않는다. 지형 높이는 `Terrain.SampleHeight()` 로 직접 샘플링한다
// (TerrainCollider 유무와 무관 · Raycast 보다 싸다). 바위·물 통과는 크기 확인용이라 신경 쓰지 않는다(발주 명시).
//
// ■ 입력 = 레거시 Input (이 프로젝트 `activeInputHandler: 0`)
// ─────────────────────────────────────────────────────────────────────────────
using UnityEngine;
namespace WL.Look.Arena
{
[DisallowMultipleComponent]
public sealed class ArenaWalker : MonoBehaviour
{
[Header("대상")]
[Tooltip("움직일 캐릭터 루트. 비우면 이 오브젝트 자신.")]
public Transform body;
[Tooltip("따라다닐 카메라. 비우면 Camera.main.")]
public Camera followCamera;
[Header("이동 (LH_M05.prefab NavMeshAgent 실측값)")]
[Tooltip("m/s · NavMeshAgent.m_Speed = 3.9")]
public float moveSpeed = 3.9f;
[Tooltip("deg/s · NavMeshAgent.m_AngularSpeed = 300")]
public float turnSpeed = 300f;
[Header("애니메이션 상태 이름 (MyValue.cs:72)")]
public string idleState = "idle";
public string runState = "run";
Animator _anim;
Vector3 _camOffset;
bool _running;
void Start()
{
if (body == null) body = transform;
if (followCamera == null) followCamera = Camera.main;
_anim = body.GetComponentInChildren<Animator>();
if (followCamera != null) _camOffset = followCamera.transform.position - body.position;
SnapToGround();
PlayState(idleState);
}
void Update()
{
if (body == null) return;
// 카메라 기준 입력(화면에서 보이는 방향대로 움직인다)
Vector3 fwd = Vector3.forward, right = Vector3.right;
if (followCamera != null)
{
fwd = Vector3.ProjectOnPlane(followCamera.transform.forward, Vector3.up);
if (fwd.sqrMagnitude < 1e-6f) fwd = Vector3.forward;
fwd.Normalize();
right = Vector3.Cross(Vector3.up, fwd);
}
Vector3 dir = right * Input.GetAxisRaw("Horizontal") + fwd * Input.GetAxisRaw("Vertical");
if (dir.sqrMagnitude > 1f) dir.Normalize();
bool moving = dir.sqrMagnitude > 1e-4f;
if (moving)
{
body.position += dir * (moveSpeed * Time.deltaTime);
body.rotation = Quaternion.RotateTowards(
body.rotation, Quaternion.LookRotation(dir, Vector3.up), turnSpeed * Time.deltaTime);
}
SnapToGround();
if (moving != _running)
{
_running = moving;
PlayState(moving ? runState : idleState);
}
}
void LateUpdate()
{
if (followCamera != null && body != null)
followCamera.transform.position = body.position + _camOffset;
}
void SnapToGround()
{
var t = Terrain.activeTerrain;
if (t == null) return;
var p = body.position;
p.y = t.SampleHeight(p) + t.transform.position.y;
body.position = p;
}
void PlayState(string state)
{
if (_anim != null && !string.IsNullOrEmpty(state)) _anim.Play(state, 0, 0f);
}
/// <summary>프로브용 — 지금까지 중앙(원점)에서 떨어진 수평 거리(m).</summary>
public float DistanceFromCenter
{
get { var p = body != null ? body.position : transform.position; return new Vector2(p.x, p.z).magnitude; }
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 8767c514397da294b856789af586ae40

View File

@ -7264,11 +7264,24 @@ PrefabInstance:
propertyPath: m_LocalRotation.z
value: -0.1736205
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedComponents:
- {fileID: 8641894914256534733, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 7018224718987816087, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 2857479151170562952, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 3657923760099891804, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 1835281278008071509, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 1155056168462878929, guid: 13b0aeca987980646af87711964339c8, type: 3}
- {fileID: 8835979289890761207, guid: 13b0aeca987980646af87711964339c8, type: 3}
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: 13b0aeca987980646af87711964339c8, type: 3}
--- !u!4 &918041735 stripped
Transform:
m_CorrespondingSourceObject: {fileID: 5000001850263733008, guid: 13b0aeca987980646af87711964339c8,
type: 3}
m_PrefabInstance: {fileID: 918041734}
m_PrefabAsset: {fileID: 0}
--- !u!1001 &929833716
PrefabInstance:
m_ObjectHideFlags: 0
@ -7724,6 +7737,7 @@ GameObject:
m_Component:
- component: {fileID: 1021739863}
- component: {fileID: 1021739864}
- component: {fileID: 1021739865}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
@ -7811,6 +7825,35 @@ Light:
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!114 &1021739865
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1021739862}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!1001 &1023981080
PrefabInstance:
m_ObjectHideFlags: 0
@ -8913,6 +8956,7 @@ GameObject:
- component: {fileID: 1166334010}
- component: {fileID: 1166334009}
- component: {fileID: 1166334008}
- component: {fileID: 1166334011}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
@ -8963,8 +9007,8 @@ Camera:
far clip plane: 500
field of view: 60
orthographic: 1
orthographic size: 3.4
m_Depth: 0
orthographic size: 10
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
@ -8987,13 +9031,57 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1166334007}
serializedVersion: 2
m_LocalRotation: {x: -0.064500555, y: 0.9143501, z: -0.36580086, w: -0.1612246}
m_LocalPosition: {x: 1.5702481, y: 5.4334784, z: 4.3142214}
m_LocalRotation: {x: 0.22414388, y: 0.48296294, z: -0.12940954, w: 0.8365163}
m_LocalPosition: {x: -22.499998, y: 15.599999, z: -12.990381}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &1166334011
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1166334007}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalCameraData
m_RenderShadows: 1
m_RequiresDepthTextureOption: 2
m_RequiresOpaqueTextureOption: 2
m_CameraType: 0
m_Cameras: []
m_RendererIndex: -1
m_VolumeLayerMask:
serializedVersion: 2
m_Bits: 1
m_VolumeTrigger: {fileID: 0}
m_VolumeFrameworkUpdateModeOption: 2
m_RenderPostProcessing: 0
m_Antialiasing: 0
m_AntialiasingQuality: 2
m_StopNaN: 0
m_Dithering: 0
m_ClearDepth: 1
m_AllowXRRendering: 1
m_AllowHDROutput: 1
m_UseScreenCoordOverride: 0
m_ScreenSizeOverride: {x: 0, y: 0, z: 0, w: 0}
m_ScreenCoordScaleBias: {x: 0, y: 0, z: 0, w: 0}
m_RequiresDepthTexture: 0
m_RequiresColorTexture: 0
m_TaaSettings:
m_Quality: 3
m_FrameInfluence: 0.1
m_JitterScale: 1
m_MipBias: 0
m_VarianceClampScale: 0.9
m_ContrastAdaptiveSharpening: 0
m_Version: 2
--- !u!1001 &1169602851
PrefabInstance:
m_ObjectHideFlags: 0
@ -12037,7 +12125,7 @@ Terrain:
m_ShadowCastingMode: 2
m_DrawHeightmap: 1
m_DrawInstanced: 0
m_DrawTreesAndFoliage: 0
m_DrawTreesAndFoliage: 1
m_StaticShadowCaster: 0
m_IgnoreQualitySettings: 0
m_ReflectionProbeUsage: 1
@ -12258,6 +12346,7 @@ GameObject:
m_Component:
- component: {fileID: 1711927570}
- component: {fileID: 1711927571}
- component: {fileID: 1711927572}
m_Layer: 0
m_Name: Point Light 0
m_TagString: Untagged
@ -12345,6 +12434,35 @@ Light:
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!114 &1711927572
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1711927569}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!1001 &1731050756
PrefabInstance:
m_ObjectHideFlags: 0
@ -13067,6 +13185,7 @@ GameObject:
m_Component:
- component: {fileID: 1861768068}
- component: {fileID: 1861768069}
- component: {fileID: 1861768070}
m_Layer: 0
m_Name: Point Light 1
m_TagString: Untagged
@ -13154,6 +13273,35 @@ Light:
m_LightUnit: 1
m_LuxAtDistance: 1
m_EnableSpotReflector: 1
--- !u!114 &1861768070
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1861768067}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 474bcb49853aa07438625e644c072ee6, type: 3}
m_Name:
m_EditorClassIdentifier: Unity.RenderPipelines.Universal.Runtime::UnityEngine.Rendering.Universal.UniversalAdditionalLightData
m_UsePipelineSettings: 1
m_AdditionalLightsShadowResolutionTier: 2
m_CustomShadowLayers: 0
m_LightCookieSize: {x: 1, y: 1}
m_LightCookieOffset: {x: 0, y: 0}
m_SoftShadowQuality: 0
m_RenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_ShadowRenderingLayersMask:
serializedVersion: 0
m_Bits: 1
m_Version: 4
m_LightLayerMask: 1
m_ShadowLayerMask: 1
m_RenderingLayers: 1
m_ShadowRenderingLayers: 1
--- !u!1001 &1867996742
PrefabInstance:
m_ObjectHideFlags: 0
@ -14359,6 +14507,56 @@ Transform:
type: 3}
m_PrefabInstance: {fileID: 2040128716}
m_PrefabAsset: {fileID: 0}
--- !u!1 &2042308454
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 2042308456}
- component: {fileID: 2042308455}
m_Layer: 0
m_Name: ArenaWalkerRig
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &2042308455
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2042308454}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 8767c514397da294b856789af586ae40, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::WL.Look.Arena.ArenaWalker
body: {fileID: 918041735}
followCamera: {fileID: 1166334009}
moveSpeed: 3.9
turnSpeed: 300
idleState: idle
runState: run
--- !u!4 &2042308456
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 2042308454}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1001 &2110215298
PrefabInstance:
m_ObjectHideFlags: 0
@ -14549,3 +14747,4 @@ SceneRoots:
- {fileID: 1881675720}
- {fileID: 918041734}
- {fileID: 1166334010}
- {fileID: 2042308456}