// ───────────────────────────────────────────────────────────────────────────── // WLMobBodySize.cs — 라인업 몹 몸 크기(ObjSize) 보정 (#907 · 2026-10-17) // // ■ 문제(실측) — 원본 Actor.Set 은 몹이 꺼진 채로 ObjSize = SkinnedMeshRenderer.bounds.size 를 읽는데, 그 값은 몹 크기 배율이 빠진 // 경계 상자 그대로다(박쥐 · 슬라임 · 플랜트 모두 localBounds 크기와 일치). 몸 중심 높이(Get_Center_position = 발 + ObjSize.y / 2 — // 몹 투사체 출발점 · 조준점)가 실제보다 높아 몬스터 플랜트 투사체가 1.10 m 높이로 날아가 PC(약 1.0 m)를 넘어갔다. // ■ 처리 — 켜진 뒤 첫 LateUpdate(같은 프레임의 원본 Set · 크기 대입이 끝난 뒤)에 ObjSize 를 다시 계산: // 가로 · 깊이 = 렌더러 경계(몹 루트 기준 localBounds — 생성기가 루트 기준으로 맞춤) × 루트 실제 크기 // 높이 = 경계 중심 높이 × 2 × 루트 실제 크기 — 떠 있는 몹(박쥐)도 중심이 몸 한가운데에 오게 // ■ 생성기(Editor/WLMobBuilder)가 라인업 프리팹 루트에 붙인다. 원본 수정 0줄. // 🔴 어셈블리 주의: Assets/WL/ 에 .asmdef 를 만들지 말 것. // ───────────────────────────────────────────────────────────────────────────── using System.Reflection; using UnityEngine; namespace WL.Mobs { [DisallowMultipleComponent] public sealed class WLMobBodySize : MonoBehaviour { static readonly FieldInfo s_objSize = typeof(Actor).GetField("ObjSize", BindingFlags.Instance | BindingFlags.NonPublic); public static int Fixed; Actor _actor; SkinnedMeshRenderer _smr; bool _pending; void Awake() { _actor = GetComponent(); _smr = GetComponentInChildren(true); } void OnEnable() { _pending = true; } void LateUpdate() { if (!_pending) return; _pending = false; if (_actor == null || _smr == null || s_objSize == null) return; var s = transform.lossyScale; var b = _smr.localBounds; float h = b.center.y > 0f ? b.center.y * 2f : b.size.y; s_objSize.SetValue(_actor, new Vector3(b.size.x * Mathf.Abs(s.x), h * Mathf.Abs(s.y), b.size.z * Mathf.Abs(s.z))); Fixed++; } } }