using System.Collections.Generic; using UnityEngine; namespace Colosseum.Player { /// /// 카메라와 타겟 사이의 장애물을 숨기는 컨트롤러 /// public class ObstacleTransparencyController : MonoBehaviour { [Header("Occlusion Settings")] [Min(0.01f)] [SerializeField] private float checkRadius = 0.3f; private Transform cameraTransform; private Transform targetTransform; private LayerMask occlusionMask; private readonly HashSet hiddenRenderers = new(); public void Initialize(Transform target, LayerMask mask) { cameraTransform = GetComponent().transform; targetTransform = target; occlusionMask = mask; } private void LateUpdate() { if (cameraTransform == null || targetTransform == null) return; Vector3 origin = cameraTransform.position; Vector3 direction = targetTransform.position - origin; float maxDistance = direction.magnitude; if (maxDistance < 0.01f) return; direction.Normalize(); HashSet currentHits = CollectHits(origin, direction, maxDistance); foreach (Renderer renderer in currentHits) { if (!hiddenRenderers.Contains(renderer)) { renderer.enabled = false; hiddenRenderers.Add(renderer); } } List toShow = null; foreach (Renderer renderer in hiddenRenderers) { if (renderer == null || !currentHits.Contains(renderer)) { if (renderer != null) renderer.enabled = true; (toShow ??= new List()).Add(renderer); } } if (toShow != null) { foreach (Renderer renderer in toShow) hiddenRenderers.Remove(renderer); } } private HashSet CollectHits(Vector3 origin, Vector3 direction, float maxDistance) { var hits = new HashSet(); int enemyLayer = LayerMask.GetMask("Enemy"); int mask = occlusionMask & ~enemyLayer; RaycastHit[] rayHits = Physics.SphereCastAll(origin, checkRadius, direction, maxDistance, mask, QueryTriggerInteraction.Ignore); float targetY = targetTransform.position.y; foreach (RaycastHit hit in rayHits) { if (hit.point.y <= targetY) continue; Renderer renderer = hit.collider.GetComponent(); if (renderer == null) continue; if (renderer is ParticleSystemRenderer || renderer is TrailRenderer) continue; hits.Add(renderer); } return hits; } public void ClearHidden() { foreach (Renderer renderer in hiddenRenderers) { if (renderer != null) renderer.enabled = true; } hiddenRenderers.Clear(); } private void OnDestroy() { ClearHidden(); } } }