115 lines
3.9 KiB
C#
115 lines
3.9 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
[System.Serializable]
|
|
public class PillarData
|
|
{
|
|
public GameObject pillarObject;
|
|
public GameObject connectedWall1;
|
|
public GameObject connectedWall2;
|
|
}
|
|
|
|
public class RoomVisibilityController : MonoBehaviour
|
|
{
|
|
[Header("Центр комнаты")]
|
|
public Transform roomCenter;
|
|
|
|
[Header("Стены (Просто перетащите 4 стены)")]
|
|
public GameObject[] walls;
|
|
|
|
[Header("Столбики")]
|
|
public PillarData[] pillars;
|
|
|
|
[Header("Настройки видимости")]
|
|
[Range(-0.5f, 0.5f)]
|
|
public float hideThreshold = 0.1f;
|
|
|
|
private Camera _mainCamera;
|
|
private Dictionary<GameObject, bool> _wallHiddenStates = new Dictionary<GameObject, bool>();
|
|
|
|
// Кэшируем Renderer'ы для оптимизации (чтобы не делать GetComponent каждый кадр)
|
|
private Dictionary<GameObject, Renderer[]> _objectRenderers = new Dictionary<GameObject, Renderer[]>();
|
|
|
|
void Start()
|
|
{
|
|
_mainCamera = Camera.main;
|
|
|
|
// При старте игры находим и запоминаем все Renderer'ы
|
|
foreach (var wall in walls) { CacheRenderers(wall); }
|
|
foreach (var pillar in pillars) { CacheRenderers(pillar.pillarObject); }
|
|
}
|
|
|
|
private void CacheRenderers(GameObject obj)
|
|
{
|
|
if (obj != null && !_objectRenderers.ContainsKey(obj))
|
|
{
|
|
_objectRenderers[obj] = obj.GetComponentsInChildren<Renderer>();
|
|
}
|
|
}
|
|
|
|
void LateUpdate()
|
|
{
|
|
if (_mainCamera == null || roomCenter == null) return;
|
|
|
|
Vector3 dirToCamera = _mainCamera.transform.position - roomCenter.position;
|
|
dirToCamera.y = 0; // Игнорируем высоту
|
|
|
|
// 1. СТЕНЫ
|
|
foreach (var wall in walls)
|
|
{
|
|
if (wall == null) continue;
|
|
|
|
Vector3 targetPos = GetRealCenter(wall);
|
|
Vector3 dirToWall = targetPos - roomCenter.position;
|
|
dirToWall.y = 0;
|
|
|
|
bool isHidden = Vector3.Dot(dirToCamera.normalized, dirToWall.normalized) > hideThreshold;
|
|
|
|
// Включаем или выключаем графику стены моментально
|
|
SetVisibility(wall, !isHidden);
|
|
_wallHiddenStates[wall] = isHidden;
|
|
|
|
Debug.DrawLine(roomCenter.position, targetPos, isHidden ? Color.red : Color.green);
|
|
}
|
|
|
|
// 2. СТОЛБИКИ
|
|
foreach (var pillar in pillars)
|
|
{
|
|
if (pillar.pillarObject == null || pillar.connectedWall1 == null || pillar.connectedWall2 == null)
|
|
continue;
|
|
|
|
bool isWall1Hidden = _wallHiddenStates.ContainsKey(pillar.connectedWall1) && _wallHiddenStates[pillar.connectedWall1];
|
|
bool isWall2Hidden = _wallHiddenStates.ContainsKey(pillar.connectedWall2) && _wallHiddenStates[pillar.connectedWall2];
|
|
|
|
// Прячем столбик только если ОБЕ подключенные стены спрятаны
|
|
bool shouldHidePillar = isWall1Hidden && isWall2Hidden;
|
|
|
|
SetVisibility(pillar.pillarObject, !shouldHidePillar);
|
|
}
|
|
}
|
|
|
|
// Метод для быстрого включения/выключения отрисовки объекта
|
|
private void SetVisibility(GameObject obj, bool isVisible)
|
|
{
|
|
if (obj == null || !_objectRenderers.ContainsKey(obj)) return;
|
|
|
|
Renderer[] renderers = _objectRenderers[obj];
|
|
foreach (Renderer r in renderers)
|
|
{
|
|
if (r.enabled != isVisible)
|
|
{
|
|
r.enabled = isVisible;
|
|
}
|
|
}
|
|
}
|
|
|
|
private Vector3 GetRealCenter(GameObject obj)
|
|
{
|
|
Renderer r = obj.GetComponentInChildren<Renderer>();
|
|
if (r != null)
|
|
{
|
|
return r.bounds.center;
|
|
}
|
|
return obj.transform.position;
|
|
}
|
|
} |