SummerGame/Assets/Scripts/RoomVisibilityController.cs

107 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>();
void Start()
{
_mainCamera = Camera.main;
}
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;
// МАГИЯ ЗДЕСЬ: берем реальный геометрический центр 3D-модели!
Vector3 targetPos = GetRealCenter(wall);
// Вектор от центра комнаты к реальному центру стены
Vector3 dirToWall = targetPos - roomCenter.position;
dirToWall.y = 0;
// Вычисляем, перекрывает ли стена камеру
bool isHidden = Vector3.Dot(dirToCamera.normalized, dirToWall.normalized) > hideThreshold;
// Рисуем линии в сцене (зеленая - видима, красная - спрятана)
Debug.DrawLine(roomCenter.position, targetPos, isHidden ? Color.red : Color.green);
// Включаем/выключаем графику
SetVisibility(wall, !isHidden);
// Запоминаем для столбиков
_wallHiddenStates[wall] = isHidden;
}
// 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 Vector3 GetRealCenter(GameObject obj)
{
Renderer r = obj.GetComponentInChildren<Renderer>();
if (r != null)
{
// bounds.center - это центр самой "коробки" 3D модели
return r.bounds.center;
}
return obj.transform.position; // Запасной вариант
}
// Метод, который выключает саму картинку (сработает даже если стена вложена в пустышку)
private void SetVisibility(GameObject obj, bool isVisible)
{
Renderer[] renderers = obj.GetComponentsInChildren<Renderer>();
foreach (Renderer r in renderers)
{
if (r.enabled != isVisible)
{
r.enabled = isVisible;
}
}
}
}