Souljack/Assets/_Project/Scripts/LevelGenerating/RoomGenerators.cs

106 lines
4.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections.Generic;
using UnityEngine;
namespace _Project.Scripts.LevelGenerating
{
// =====================================================================
// Генератор, который оформляет одну комнату после того, как построены её меши.
// Специальные комнаты (лифт, старт) получают свои реализации,
// обычные - универсальный ThemedRoomGenerator.
// =====================================================================
public interface IRoomGenerator
{
bool Supports(Room room);
void Generate(RoomView view, FloorData floor, RoomTheme theme);
}
// Универсальный генератор: материалы из темы и сетка светильников под потолком.
// Позже сюда добавится расстановка предметов по правилам темы.
public class ThemedRoomGenerator : IRoomGenerator
{
public bool Supports(Room room) => true;
public void Generate(RoomView view, FloorData floor, RoomTheme theme)
{
if (theme == null)
{
Debug.LogWarning($"{view.name}: для комнаты не назначена тема");
return;
}
ApplyMaterial(view.FloorRenderers, theme.floorMaterial);
ApplyMaterial(view.WallRenderers, theme.wallMaterial);
ApplyMaterial(view.CeilingRenderers, theme.ceilingMaterial);
if (theme.lightConfig != null)
{
CreateLights(view, theme.lightConfig);
RuntimeRoomLightmapBaker.BakeRoom(view, theme.lightConfig); // <-- ЗАПЕКАЕМ СВЕТ НА ЛЕТУ!
}
}
private static void ApplyMaterial(List<Renderer> renderers, Material mat)
{
if (mat == null) return; // остаётся материал префаба
foreach (var r in renderers) r.sharedMaterial = mat;
}
// Сетка светильников: спавнит префаб из RoomLightConfig и применяет параметры
private static void CreateLights(RoomView view, RoomLightConfig config)
{
Vector3 size = view.SizeMeters;
Vector3 origin = view.OriginMeters;
float spacing = Mathf.Max(0.5f, config.spacing);
int nx = Mathf.Max(1, Mathf.CeilToInt(size.x / spacing));
int nz = Mathf.Max(1, Mathf.CeilToInt(size.z / spacing));
float y = view.Height - config.ceilingDrop;
var lightsRoot = new GameObject("Lights").transform;
lightsRoot.SetParent(view.transform, false);
Quaternion rot = Quaternion.Euler(config.rotationOffset);
for (int ix = 0; ix < nx; ix++)
{
for (int iz = 0; iz < nz; iz++)
{
Vector3 pos = origin + new Vector3(
(ix + 0.5f) / nx * size.x,
y,
(iz + 0.5f) / nz * size.z);
GameObject lightGo;
if (config.lightPrefab != null)
{
lightGo = Object.Instantiate(config.lightPrefab, pos, rot, lightsRoot);
lightGo.name = $"{config.lightPrefab.name}_{ix}_{iz}";
}
else
{
// Запасной вариант, если префаб забыли назначить в SO
lightGo = new GameObject($"FallbackLight_{ix}_{iz}");
lightGo.transform.SetParent(lightsRoot, false);
lightGo.transform.SetPositionAndRotation(pos, rot);
var fallbackLight = lightGo.AddComponent<Light>();
fallbackLight.type = LightType.Point;
}
// Если включена перезапись параметров (или сработал запасной вариант без префаба)
if (config.overrideLightParameters || config.lightPrefab == null)
{
var lights = lightGo.GetComponentsInChildren<Light>(true);
foreach (var l in lights)
{
l.color = config.color;
l.intensity = config.intensity;
l.range = config.range;
l.shadows = config.shadows;
}
}
}
}
}
}
}