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(); 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(PROPS_DIR + "CR_Lab2_Desk_01.prefab"); compPrefab = AssetDatabase.LoadAssetAtPath(PROPS_DIR + "CR_Lab2_Computer_01.prefab"); microPrefab = AssetDatabase.LoadAssetAtPath(PROPS_DIR + "CR_Lab2_Microscope.prefab"); notePrefab = AssetDatabase.LoadAssetAtPath(PROPS_DIR + "CR_Lab2_Notebook.prefab"); stoolPrefab = AssetDatabase.LoadAssetAtPath(PROPS_DIR + "CR_Lab2_Stool.prefab"); capsulePrefab = AssetDatabase.LoadAssetAtPath(PROPS_DIR + "CR_Lab2_Capsule_01.prefab"); alienPrefab = AssetDatabase.LoadAssetAtPath(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(); 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); } } }