288 lines
15 KiB
C#
288 lines
15 KiB
C#
using System.IO;
|
||
using UnityEditor;
|
||
using UnityEditor.SceneManagement;
|
||
using UnityEngine;
|
||
using UnityEngine.SceneManagement;
|
||
|
||
public static class CosmicRetroLabIntegrator
|
||
{
|
||
private const string ROOT_NAME = "Cosmic_Retro_Laboratory";
|
||
private const string PROPS_DIR = "Assets/room/Cosmic_Retro_Laboratory_2_Demo/Prefabs/Props/";
|
||
|
||
private static GameObject deskPrefab;
|
||
private static GameObject compPrefab;
|
||
private static GameObject microPrefab;
|
||
private static GameObject notePrefab;
|
||
private static GameObject stoolPrefab;
|
||
private static GameObject capsulePrefab;
|
||
private static GameObject alienPrefab;
|
||
|
||
[MenuItem("Tools/Integrate Cosmic Retro Laboratory")]
|
||
public static void Integrate()
|
||
{
|
||
LoadPrefabs();
|
||
|
||
// 1. Найти или очистить предыдущую интеграцию
|
||
var existingRoot = GameObject.Find(ROOT_NAME);
|
||
if (existingRoot != null)
|
||
{
|
||
Undo.DestroyObjectImmediate(existingRoot);
|
||
}
|
||
|
||
var rootGo = new GameObject(ROOT_NAME);
|
||
Undo.RegisterCreatedObjectUndo(rootGo, "Integrate Cosmic Retro Lab");
|
||
|
||
// 2. Интеграция по секторам исследовательского комплекса
|
||
BuildAirlockSector(rootGo.transform);
|
||
BuildSouthConcourseSector(rootGo.transform);
|
||
BuildGrandAtriumSector(rootGo.transform);
|
||
BuildBiochemLabSector(rootGo.transform);
|
||
BuildGeneticsWingSector(rootGo.transform);
|
||
BuildCryoVaultSector(rootGo.transform);
|
||
BuildSurgicalSector(rootGo.transform);
|
||
BuildQuarantineSector(rootGo.transform);
|
||
|
||
// 3. Обновить список материалов эхолокации в EchoTrigger (если компонент в сцене)
|
||
var echoTrigger = Object.FindAnyObjectByType<EchoTrigger>();
|
||
if (echoTrigger != null)
|
||
{
|
||
echoTrigger.CollectAllEchoMaterials();
|
||
EditorUtility.SetDirty(echoTrigger);
|
||
}
|
||
|
||
// 4. Сохранить изменения в открытой сцене и синхронизировать с SampleScene.unity
|
||
var activeScene = SceneManager.GetActiveScene();
|
||
EditorSceneManager.MarkSceneDirty(activeScene);
|
||
EditorSceneManager.SaveScene(activeScene);
|
||
|
||
string sampleScenePath = "Assets/Scenes/SampleScene.unity";
|
||
if (activeScene.path != sampleScenePath)
|
||
{
|
||
EditorSceneManager.SaveScene(activeScene, sampleScenePath, true);
|
||
}
|
||
|
||
AssetDatabase.SaveAssets();
|
||
|
||
Debug.Log($"[CosmicRetroLabIntegrator] Успешно интегрировано 73 объекта Cosmic Retro Laboratory в сцену '{activeScene.name}' ({activeScene.path}) и сохранено в '{sampleScenePath}'!");
|
||
}
|
||
|
||
private static void LoadPrefabs()
|
||
{
|
||
deskPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Desk_01.prefab");
|
||
compPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Computer_01.prefab");
|
||
microPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Microscope.prefab");
|
||
notePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Notebook.prefab");
|
||
stoolPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Stool.prefab");
|
||
capsulePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Capsule_01.prefab");
|
||
alienPrefab = AssetDatabase.LoadAssetAtPath<GameObject>(PROPS_DIR + "CR_Lab2_Alien_01.prefab");
|
||
|
||
if (deskPrefab == null || compPrefab == null || capsulePrefab == null || alienPrefab == null)
|
||
{
|
||
throw new System.Exception("Не удалось загрузить один или несколько префабов Cosmic Retro!");
|
||
}
|
||
}
|
||
|
||
// --- СЕКТОР 1: Входной шлюз / Точка появления игрока (Spawn: 0, 1.05, -44) ---
|
||
private static void BuildAirlockSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "01_Airlock_Spawn");
|
||
|
||
// Приемный терминал службы безопасности (справа от игрока, экран виден при движении на север)
|
||
SpawnWorkstation(sector, new Vector3(3.2f, 0.0f, -42.5f), -90f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Security_Console");
|
||
|
||
// Первая капсула со спящим пришельцем у шлюза
|
||
SpawnCapsuleWithAlien(sector, new Vector3(3.2f, 0.0f, -45.0f), Quaternion.Euler(0, -45f, 0), "Airlock_Stasis_Capsule");
|
||
}
|
||
|
||
// --- СЕКТОР 2: Южный переходной коридор (Z ~ -30) ---
|
||
private static void BuildSouthConcourseSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "02_SouthConcourse");
|
||
|
||
// Наблюдательный терминал коридора
|
||
SpawnWorkstation(sector, new Vector3(-4.5f, 0.0f, -29.5f), 0f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Concourse_Terminal");
|
||
|
||
// Капсула с биологическим образцом в восточной нише
|
||
SpawnCapsuleWithAlien(sector, new Vector3(4.5f, 0.0f, -29.5f), Quaternion.Euler(0, 180f, 0), "Concourse_Specimen_Pod");
|
||
}
|
||
|
||
// --- СЕКТОР 3: Главный Атриум / Центральный исследовательский хаб ---
|
||
private static void BuildGrandAtriumSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "03_GrandAtrium");
|
||
|
||
// Двойной центральный пост мониторинга
|
||
SpawnWorkstation(sector, new Vector3(-3.0f, 0.0f, 3.0f), 45f,
|
||
withComputer: true, withMicroscope: true, withNotebook: true, withStool: true, "Atrium_Command_Station_Alpha");
|
||
|
||
SpawnWorkstation(sector, new Vector3(3.0f, 0.0f, 3.0f), -45f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Atrium_Command_Station_Beta");
|
||
|
||
// Парные стазис-капсулы в центре атриума
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-5.0f, 0.0f, 7.5f), Quaternion.Euler(0, 45f, 0), "Atrium_Containment_Pod_Left");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(5.0f, 0.0f, 7.5f), Quaternion.Euler(0, -45f, 0), "Atrium_Containment_Pod_Right");
|
||
}
|
||
|
||
// --- СЕКТОР 4: Биохимическая лаборатория (Сектор D, X ~ -40, Z ~ -10) ---
|
||
private static void BuildBiochemLabSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "04_BiochemistryLab");
|
||
|
||
// Исследовательский пост биохимического синтеза (микроскоп, компьютер, блокнот)
|
||
SpawnWorkstation(sector, new Vector3(-38.0f, 0.0f, -6.5f), 90f,
|
||
withComputer: true, withMicroscope: true, withNotebook: true, withStool: true, "Biochem_Analysis_Desk_01");
|
||
|
||
// Вспомогательный рабочий стол анализа проб
|
||
SpawnWorkstation(sector, new Vector3(-38.0f, 0.0f, -13.5f), 90f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Biochem_Analysis_Desk_02");
|
||
|
||
// Биохимические инкубаторы с пришельцами
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-43.0f, 0.0f, -6.5f), Quaternion.Euler(0, 135f, 0), "Biochem_Incubator_01");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-43.0f, 0.0f, -13.5f), Quaternion.Euler(0, 45f, 0), "Biochem_Incubator_02");
|
||
}
|
||
|
||
// --- СЕКТОР 5: Отсек генетики и мутагенеза (Сектор G, X ~ +39, Z ~ +15) ---
|
||
private static void BuildGeneticsWingSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "05_GeneticsWing");
|
||
|
||
// Рабочее место генного инженера
|
||
SpawnWorkstation(sector, new Vector3(36.0f, 0.0f, 15.5f), 90f,
|
||
withComputer: true, withMicroscope: true, withNotebook: true, withStool: true, "Genetics_Console");
|
||
|
||
// Тройная шеренга генетических инкубационных капсул
|
||
SpawnCapsuleWithAlien(sector, new Vector3(42.5f, 0.0f, 13.5f), Quaternion.Euler(0, -90f, 0), "Genetics_Incubator_Pod_1");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(42.5f, 0.0f, 15.8f), Quaternion.Euler(0, -90f, 0), "Genetics_Incubator_Pod_2");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(42.5f, 0.0f, 18.0f), Quaternion.Euler(0, -90f, 0), "Genetics_Incubator_Pod_3");
|
||
}
|
||
|
||
// --- СЕКТОР 6: Криогенное хранилище / Стазис-сектор (Сектор B, X ~ -36, Z ~ -37) ---
|
||
private static void BuildCryoVaultSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "06_CryoVault");
|
||
|
||
// Главный пульт криогенного управления
|
||
SpawnWorkstation(sector, new Vector3(-36.5f, 0.0f, -33.5f), 180f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Cryo_Master_Terminal");
|
||
|
||
// Банк из четырех крио-капсул глубокой заморозки
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-33.0f, 0.0f, -41.0f), Quaternion.identity, "Cryo_Stasis_Tank_01");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-35.5f, 0.0f, -41.0f), Quaternion.identity, "Cryo_Stasis_Tank_02");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-38.0f, 0.0f, -41.0f), Quaternion.identity, "Cryo_Stasis_Tank_03");
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-40.5f, 0.0f, -41.0f), Quaternion.identity, "Cryo_Stasis_Tank_04");
|
||
}
|
||
|
||
// --- СЕКТОР 7: Хирургический бокс / Медблок (Сектор E, X ~ +39, Z ~ -10) ---
|
||
private static void BuildSurgicalSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "07_SurgicalTheatre");
|
||
|
||
// Диагностический пост хирурга
|
||
SpawnWorkstation(sector, new Vector3(36.5f, 0.0f, -9.5f), 90f,
|
||
withComputer: true, withMicroscope: true, withNotebook: true, withStool: true, "Surgical_Diagnostics_Desk");
|
||
|
||
// Изолированная капсула для автопсий и исследований
|
||
SpawnCapsuleWithAlien(sector, new Vector3(43.0f, 0.0f, -9.5f), Quaternion.Euler(0, -90f, 0), "Surgical_Stasis_Pod");
|
||
}
|
||
|
||
// --- СЕКТОР 8: Карантинный изолятор (Сектор C, X ~ -35, Z ~ +16) ---
|
||
private static void BuildQuarantineSector(Transform parent)
|
||
{
|
||
var sector = CreateSector(parent, "08_QuarantineBay");
|
||
|
||
// Пост наблюдения за карантинным блоком
|
||
SpawnWorkstation(sector, new Vector3(-32.0f, 0.0f, 16.0f), -90f,
|
||
withComputer: true, withMicroscope: false, withNotebook: true, withStool: true, "Quarantine_Observation_Desk");
|
||
|
||
// Высокозащищенная капсула изоляции
|
||
SpawnCapsuleWithAlien(sector, new Vector3(-39.0f, 0.0f, 16.0f), Quaternion.Euler(0, 90f, 0), "BioHazard_Isolation_Pod");
|
||
}
|
||
|
||
// --- ХЕЛПЕРЫ ДЛЯ СПАВНА И ПОЗИЦИОНИРОВАНИЯ ---
|
||
private static Transform CreateSector(Transform parent, string name)
|
||
{
|
||
var go = new GameObject(name);
|
||
go.transform.SetParent(parent, false);
|
||
return go.transform;
|
||
}
|
||
|
||
private static void SpawnCapsuleWithAlien(Transform parent, Vector3 pos, Quaternion rot, string name)
|
||
{
|
||
var capsule = (GameObject)PrefabUtility.InstantiatePrefab(capsulePrefab);
|
||
capsule.name = name;
|
||
capsule.transform.SetParent(parent, false);
|
||
capsule.transform.position = pos;
|
||
capsule.transform.rotation = rot;
|
||
|
||
// Пришелец размещается ровно внутри капсулы на высоте 0.92 м
|
||
var alien = (GameObject)PrefabUtility.InstantiatePrefab(alienPrefab);
|
||
alien.name = "Specimen_" + name;
|
||
alien.transform.SetParent(capsule.transform, false);
|
||
alien.transform.localPosition = new Vector3(0.0f, 0.92f, 0.0f);
|
||
alien.transform.localRotation = Quaternion.identity;
|
||
|
||
// Отключаем прямой коллайдер пришельца, чтобы он не конфликтовал со стеклянной оболочкой капсулы
|
||
var col = alien.GetComponent<Collider>();
|
||
if (col != null) col.enabled = false;
|
||
}
|
||
|
||
private static void SpawnWorkstation(Transform parent, Vector3 deskPos, float rotY,
|
||
bool withComputer, bool withMicroscope, bool withNotebook, bool withStool, string stationName)
|
||
{
|
||
var station = new GameObject(stationName);
|
||
station.transform.SetParent(parent, false);
|
||
station.transform.position = deskPos;
|
||
station.transform.rotation = Quaternion.Euler(0f, rotY, 0f);
|
||
|
||
// Стол
|
||
var desk = (GameObject)PrefabUtility.InstantiatePrefab(deskPrefab);
|
||
desk.name = "Desk";
|
||
desk.transform.SetParent(station.transform, false);
|
||
desk.transform.localPosition = Vector3.zero;
|
||
desk.transform.localRotation = Quaternion.identity;
|
||
|
||
// Компьютер (слева на столе, высота поверхности стола = 0.81м)
|
||
if (withComputer)
|
||
{
|
||
var comp = (GameObject)PrefabUtility.InstantiatePrefab(compPrefab);
|
||
comp.name = "Computer_Terminal";
|
||
comp.transform.SetParent(station.transform, false);
|
||
comp.transform.localPosition = new Vector3(-0.35f, 0.81f, 0.05f);
|
||
comp.transform.localRotation = Quaternion.identity;
|
||
}
|
||
|
||
// Микроскоп (справа на столе)
|
||
if (withMicroscope)
|
||
{
|
||
var micro = (GameObject)PrefabUtility.InstantiatePrefab(microPrefab);
|
||
micro.name = "Research_Microscope";
|
||
micro.transform.SetParent(station.transform, false);
|
||
micro.transform.localPosition = new Vector3(0.38f, 0.81f, 0.08f);
|
||
micro.transform.localRotation = Quaternion.Euler(0f, -15f, 0f);
|
||
}
|
||
|
||
// Блокнот / Журнал наблюдений (по центру/справа перед исследователем)
|
||
if (withNotebook)
|
||
{
|
||
var note = (GameObject)PrefabUtility.InstantiatePrefab(notePrefab);
|
||
note.name = "Lab_Notebook";
|
||
note.transform.SetParent(station.transform, false);
|
||
float noteX = withMicroscope ? 0.20f : 0.30f;
|
||
note.transform.localPosition = new Vector3(noteX, 0.81f, -0.15f);
|
||
note.transform.localRotation = Quaternion.Euler(0f, 12f, 0f);
|
||
}
|
||
|
||
// Табурет перед столом
|
||
if (withStool)
|
||
{
|
||
var stool = (GameObject)PrefabUtility.InstantiatePrefab(stoolPrefab);
|
||
stool.name = "Swivel_Stool";
|
||
stool.transform.SetParent(station.transform, false);
|
||
stool.transform.localPosition = new Vector3(0.0f, 0.0f, -0.75f);
|
||
stool.transform.localRotation = Quaternion.Euler(0f, 25f, 0f);
|
||
}
|
||
}
|
||
}
|