107 lines
3.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |