77 lines
2.6 KiB
C#
77 lines
2.6 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
|
|||
|
|
public class PlayerRangeManager : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
[Header("--- 대상 설정 ---")]
|
|||
|
|
[SerializeField] private Transform environmentParent; // 맵 오브젝트 부모 폴더
|
|||
|
|
|
|||
|
|
[Header("--- 최적화 설정 ---")]
|
|||
|
|
[SerializeField] private float renderRange = 40f; // ⭐ 반드시 30~50 사이로 키워주세요!
|
|||
|
|
[SerializeField] private float checkInterval = 0.2f;
|
|||
|
|
|
|||
|
|
private struct RenderGroup
|
|||
|
|
{
|
|||
|
|
public Vector3 actualCenter; // ⭐ 피벗이 아닌 실제 메쉬의 중심점
|
|||
|
|
public Renderer[] renderers;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private List<RenderGroup> _childGroups = new List<RenderGroup>();
|
|||
|
|
private Transform _player;
|
|||
|
|
|
|||
|
|
private void Start()
|
|||
|
|
{
|
|||
|
|
// 태그로 플레이어를 정확히 찾습니다.
|
|||
|
|
GameObject playerObj = GameObject.FindGameObjectWithTag("Player");
|
|||
|
|
if (playerObj != null) _player = playerObj.transform;
|
|||
|
|
else _player = transform;
|
|||
|
|
|
|||
|
|
if (environmentParent != null) RefreshChildList();
|
|||
|
|
InvokeRepeating(nameof(UpdateCulling), 0f, checkInterval);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void RefreshChildList()
|
|||
|
|
{
|
|||
|
|
if (environmentParent == null) return;
|
|||
|
|
_childGroups.Clear();
|
|||
|
|
|
|||
|
|
foreach (Transform child in environmentParent)
|
|||
|
|
{
|
|||
|
|
Renderer[] rs = child.GetComponentsInChildren<Renderer>(true);
|
|||
|
|
if (rs.Length > 0)
|
|||
|
|
{
|
|||
|
|
// ⭐ [수정] 피벗(position)이 아니라, 실제 모델링의 중심(bounds.center)을 가져옵니다.
|
|||
|
|
// 이래야 "가까이 갔는데 꺼지는" 현상이 완벽히 해결됩니다!
|
|||
|
|
Vector3 center = rs[0].bounds.center;
|
|||
|
|
_childGroups.Add(new RenderGroup { actualCenter = center, renderers = rs });
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateCulling()
|
|||
|
|
{
|
|||
|
|
if (_player == null) return;
|
|||
|
|
Vector3 playerPos = _player.position;
|
|||
|
|
|
|||
|
|
foreach (var group in _childGroups)
|
|||
|
|
{
|
|||
|
|
// ⭐ [핵심] 실제 몸통 중심점과의 거리를 계산합니다.
|
|||
|
|
float dist = Vector3.Distance(playerPos, group.actualCenter);
|
|||
|
|
bool shouldShow = dist <= renderRange;
|
|||
|
|
|
|||
|
|
foreach (Renderer r in group.renderers)
|
|||
|
|
{
|
|||
|
|
if (r != null && r.enabled != shouldShow) r.enabled = shouldShow;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnDrawGizmos()
|
|||
|
|
{
|
|||
|
|
if (_player != null)
|
|||
|
|
{
|
|||
|
|
Gizmos.color = Color.red;
|
|||
|
|
Gizmos.DrawWireSphere(_player.position, renderRange); // 플레이어를 따라다니는 빨간 원
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|