using System.Collections.Generic; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Rendering; using UnityEngine.UI; public static class Lab4SceneBuilder { private const string ScenePath = "Assets/Scenes/Lab4_NarrativeExploration.unity"; private const string MaterialsFolder = "Assets/Materials/Lab4"; private sealed class BuilderAssets { public Font font; public Material floorMaterial; public Material wallMaterial; public Material accentMaterial; public Material woodMaterial; public Material noteMaterial; public Material highlightMaterial; public Material npcMaterial; public Material doorMaterial; public Material decorMaterial; } private sealed class UIContext { public GameObject notePanel; public Text noteTitleText; public Text noteContentText; public Button noteCloseButton; public GameObject inventoryPanel; public Transform inventoryContentRoot; public Button inventoryButtonTemplate; public Text inventoryEmptyText; public Button inventoryCloseButton; public GameObject dialoguePanel; public Text dialogueNameText; public Text dialogueBodyText; public Transform dialogueOptionsRoot; public Button dialogueOptionTemplate; public Button dialogueCloseButton; public GameObject promptPanel; public Text promptText; public Text questStatusText; public GameObject questCompletePanel; public Text questCompleteText; public GameObject levelCompletePanel; public Text levelCompleteText; } [MenuItem("Tools/Lab4/Create Full Test Scene")] public static void CreateFullTestScene() { EnsureFolder("Assets/Materials"); EnsureFolder(MaterialsFolder); EnsureFolder("Assets/Scenes"); EnsureTag("Player"); var scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); scene.name = "Lab4_NarrativeExploration"; var assets = CreateAssets(); ConfigureLightingAndEnvironment(); var root = new GameObject("Lab4_Root"); var environmentRoot = new GameObject("Environment"); environmentRoot.transform.SetParent(root.transform); CreateDirectionalLight(root.transform); CreateLevelGeometry(environmentRoot.transform, assets, out var exitDoor, out var exitTrigger); CreateDecor(environmentRoot.transform, assets); var ui = CreateUI(root.transform, assets); CreateEventSystem(root.transform); CreateGameSystems(root.transform, ui, exitDoor, exitTrigger); CreatePlayer(root.transform); CreateNotes(root.transform, assets); CreateNpc(root.transform, assets); EditorSceneManager.MarkSceneDirty(scene); EditorSceneManager.SaveScene(scene, ScenePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); var sceneAsset = AssetDatabase.LoadAssetAtPath(ScenePath); if (sceneAsset != null) { EditorGUIUtility.PingObject(sceneAsset); } EditorUtility.DisplayDialog( "Lab4 Scene Builder", "Сцена Lab4_NarrativeExploration создана и сохранена в Assets/Scenes.", "OK"); } private static BuilderAssets CreateAssets() { return new BuilderAssets { font = Resources.GetBuiltinResource("LegacyRuntime.ttf"), floorMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Floor.mat", new Color(0.34f, 0.38f, 0.42f), 0.05f), wallMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Wall.mat", new Color(0.75f, 0.71f, 0.62f), 0.12f), accentMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Accent.mat", new Color(0.22f, 0.47f, 0.49f), 0.15f), woodMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Wood.mat", new Color(0.44f, 0.29f, 0.18f), 0.18f), noteMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Note.mat", new Color(0.93f, 0.89f, 0.73f), 0.05f), highlightMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Highlight.mat", new Color(0.98f, 0.82f, 0.21f), 0.03f), npcMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/NPC.mat", new Color(0.31f, 0.52f, 0.82f), 0.18f), doorMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Door.mat", new Color(0.58f, 0.17f, 0.16f), 0.2f), decorMaterial = CreateOrUpdateMaterial($"{MaterialsFolder}/Decor.mat", new Color(0.52f, 0.56f, 0.35f), 0.08f) }; } private static void ConfigureLightingAndEnvironment() { RenderSettings.ambientMode = AmbientMode.Flat; RenderSettings.ambientLight = new Color(0.62f, 0.65f, 0.7f); RenderSettings.fog = true; RenderSettings.fogColor = new Color(0.69f, 0.71f, 0.75f); RenderSettings.fogDensity = 0.01f; } private static void CreateDirectionalLight(Transform parent) { var lightObject = new GameObject("Directional Light"); lightObject.transform.SetParent(parent); lightObject.transform.rotation = Quaternion.Euler(50f, -30f, 0f); var directionalLight = lightObject.AddComponent(); directionalLight.type = LightType.Directional; directionalLight.intensity = 1.2f; directionalLight.shadows = LightShadows.Soft; } private static void CreateLevelGeometry(Transform parent, BuilderAssets assets, out GameObject exitDoor, out GameObject exitTrigger) { CreatePlane("Floor", parent, Vector3.zero, new Vector3(3.2f, 1f, 3.2f), assets.floorMaterial); CreateCube("NorthWall", parent, new Vector3(0f, 2f, 12f), new Vector3(24f, 4f, 0.5f), assets.wallMaterial); CreateCube("SouthWall", parent, new Vector3(0f, 2f, -12f), new Vector3(24f, 4f, 0.5f), assets.wallMaterial); CreateCube("WestWall", parent, new Vector3(-12f, 2f, 0f), new Vector3(0.5f, 4f, 24f), assets.wallMaterial); CreateCube("EastWall", parent, new Vector3(12f, 2f, 0f), new Vector3(0.5f, 4f, 24f), assets.wallMaterial); CreateCube("InnerWall_A1", parent, new Vector3(-4f, 2f, 8.5f), new Vector3(0.5f, 4f, 7f), assets.wallMaterial); CreateCube("InnerWall_A2", parent, new Vector3(-4f, 2f, -6f), new Vector3(0.5f, 4f, 12f), assets.wallMaterial); CreateCube("InnerWall_B1", parent, new Vector3(4f, 2f, 5f), new Vector3(0.5f, 4f, 14f), assets.wallMaterial); CreateCube("InnerWall_B2", parent, new Vector3(4f, 2f, -10.5f), new Vector3(0.5f, 4f, 3f), assets.wallMaterial); CreateCube("InnerWall_C1", parent, new Vector3(-7.5f, 2f, 0f), new Vector3(8f, 4f, 0.5f), assets.wallMaterial); CreateCube("InnerWall_C2", parent, new Vector3(7.5f, 2f, 0f), new Vector3(7f, 4f, 0.5f), assets.wallMaterial); CreateCube("InnerWall_D", parent, new Vector3(0f, 2f, 7f), new Vector3(11f, 4f, 0.5f), assets.wallMaterial); CreateCube("AccentStrip_1", parent, new Vector3(-8f, 0.05f, 6f), new Vector3(6f, 0.1f, 4f), assets.accentMaterial); CreateCube("AccentStrip_2", parent, new Vector3(7f, 0.05f, -6f), new Vector3(4f, 0.1f, 6f), assets.accentMaterial); var exitRoot = new GameObject("Exit"); exitRoot.transform.SetParent(parent); exitRoot.transform.position = new Vector3(11.5f, 0f, 6f); CreateCube("ExitFrame_Left", exitRoot.transform, new Vector3(0f, 1.5f, -1.25f), new Vector3(0.5f, 3f, 0.5f), assets.woodMaterial); CreateCube("ExitFrame_Right", exitRoot.transform, new Vector3(0f, 1.5f, 1.25f), new Vector3(0.5f, 3f, 0.5f), assets.woodMaterial); CreateCube("ExitFrame_Top", exitRoot.transform, new Vector3(0f, 3.1f, 0f), new Vector3(0.5f, 0.35f, 3f), assets.woodMaterial); exitDoor = CreateCube("ExitDoor", exitRoot.transform, new Vector3(0f, 1.5f, 0f), new Vector3(0.2f, 3f, 2.3f), assets.doorMaterial); exitTrigger = new GameObject("ExitTrigger"); exitTrigger.transform.SetParent(exitRoot.transform); exitTrigger.transform.localPosition = new Vector3(0.9f, 1.2f, 0f); var triggerCollider = exitTrigger.AddComponent(); triggerCollider.isTrigger = true; triggerCollider.size = new Vector3(2.2f, 2.4f, 2.6f); exitTrigger.AddComponent(); exitTrigger.SetActive(false); } private static void CreateDecor(Transform parent, BuilderAssets assets) { CreateTable(parent, new Vector3(-8f, 0f, 8f), assets.woodMaterial); CreateTable(parent, new Vector3(-9f, 0f, -7f), assets.woodMaterial); CreateTable(parent, new Vector3(0f, 0f, -7f), assets.woodMaterial); CreateTable(parent, new Vector3(8f, 0f, 8f), assets.woodMaterial); CreateCrate(parent, new Vector3(-8f, 0.5f, -2f), new Vector3(1.2f, 1.2f, 1.2f), assets.decorMaterial); CreateCrate(parent, new Vector3(-6.3f, 0.4f, -2.3f), new Vector3(0.8f, 0.8f, 0.8f), assets.decorMaterial); CreateCrate(parent, new Vector3(2.5f, 0.5f, -5f), new Vector3(1.2f, 1.2f, 1.2f), assets.decorMaterial); CreateCrate(parent, new Vector3(3.7f, 1.1f, -4.3f), new Vector3(0.8f, 0.8f, 0.8f), assets.decorMaterial); CreateCrate(parent, new Vector3(7f, 0.6f, 3f), new Vector3(1.3f, 1.3f, 1.3f), assets.decorMaterial); CreateShelf(parent, new Vector3(8.5f, 0f, 9.8f), assets.woodMaterial, assets.decorMaterial); CreateShelf(parent, new Vector3(-10.2f, 0f, 9.8f), assets.woodMaterial, assets.decorMaterial); CreateBench(parent, new Vector3(1.5f, 0f, 9.2f), assets.woodMaterial); CreateColumn(parent, new Vector3(-1f, 1.5f, 3f), assets.accentMaterial); CreateColumn(parent, new Vector3(10f, 1.5f, -8f), assets.accentMaterial); CreateSphere("MarkerOrb_1", parent, new Vector3(-10f, 0.8f, 4f), new Vector3(0.7f, 0.7f, 0.7f), assets.accentMaterial); CreateSphere("MarkerOrb_2", parent, new Vector3(6f, 0.8f, -10f), new Vector3(0.7f, 0.7f, 0.7f), assets.npcMaterial); } private static UIContext CreateUI(Transform parent, BuilderAssets assets) { var context = new UIContext(); var canvasObject = new GameObject("Canvas"); canvasObject.transform.SetParent(parent); var canvas = canvasObject.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; var scaler = canvasObject.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1920f, 1080f); scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight; scaler.matchWidthOrHeight = 0.5f; canvasObject.AddComponent(); CreateControlHintPanel(canvasObject.transform, assets); context.questStatusText = CreateQuestStatusPanel(canvasObject.transform, assets); CreateInventoryPanel(canvasObject.transform, assets, context); CreateNotePanel(canvasObject.transform, assets, context); CreateDialoguePanel(canvasObject.transform, assets, context); CreateInteractionPrompt(canvasObject.transform, assets, context); CreateQuestCompletePanel(canvasObject.transform, assets, context); return context; } private static void CreateControlHintPanel(Transform parent, BuilderAssets assets) { var panel = CreatePanel( "ControlsPanel", parent, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(20f, -20f), new Vector2(320f, 140f), new Color(0.1f, 0.12f, 0.16f, 0.82f), null); CreateText( "ControlsText", panel.transform, "WASD — движение\nМышь — обзор\nE — взаимодействовать\nI — инвентарь", assets.font, 24, TextAnchor.UpperLeft, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(8f, -8f), new Vector2(-16f, -16f), Color.white); } private static Text CreateQuestStatusPanel(Transform parent, BuilderAssets assets) { var panel = CreatePanel( "QuestStatusPanel", parent, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-20f, -20f), new Vector2(360f, 140f), new Color(0.08f, 0.18f, 0.2f, 0.86f), null); return CreateText( "QuestStatusText", panel.transform, "Записки: 0/3\nДиалог с NPC: ✗\nСтатус: исследуйте уровень", assets.font, 24, TextAnchor.UpperLeft, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(12f, -12f), new Vector2(-24f, -24f), Color.white); } private static void CreateInventoryPanel(Transform parent, BuilderAssets assets, UIContext context) { var panel = CreatePanel( "InventoryPanel", parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(760f, 560f), new Color(0.12f, 0.13f, 0.18f, 0.96f), null); context.inventoryPanel = panel; panel.SetActive(false); CreateText( "InventoryTitle", panel.transform, "Инвентарь записок", assets.font, 34, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(28f, -18f), new Vector2(-180f, 54f), Color.white); context.inventoryCloseButton = CreateButton( "CloseInventoryButton", panel.transform, "Закрыть", assets, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-30f, -24f), new Vector2(150f, 48f), new Color(0.57f, 0.24f, 0.2f, 1f)); CreatePanel( "InventoryBody", panel.transform, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, -20f), new Vector2(-50f, -120f), new Color(0.18f, 0.19f, 0.24f, 0.92f), null); var scrollView = new GameObject("InventoryScrollView"); scrollView.transform.SetParent(panel.transform, false); var scrollRectTransform = scrollView.AddComponent(); scrollRectTransform.anchorMin = new Vector2(0f, 0f); scrollRectTransform.anchorMax = new Vector2(1f, 1f); scrollRectTransform.offsetMin = new Vector2(28f, 28f); scrollRectTransform.offsetMax = new Vector2(-28f, -92f); var scrollImage = scrollView.AddComponent(); scrollImage.sprite = null; scrollImage.type = Image.Type.Simple; scrollImage.color = new Color(0.14f, 0.15f, 0.2f, 0.92f); var scrollRect = scrollView.AddComponent(); scrollRect.horizontal = false; scrollRect.scrollSensitivity = 25f; var viewport = new GameObject("Viewport"); viewport.transform.SetParent(scrollView.transform, false); var viewportRect = viewport.AddComponent(); viewportRect.anchorMin = Vector2.zero; viewportRect.anchorMax = Vector2.one; viewportRect.offsetMin = Vector2.zero; viewportRect.offsetMax = Vector2.zero; var viewportImage = viewport.AddComponent(); viewportImage.sprite = null; viewportImage.type = Image.Type.Simple; viewportImage.color = new Color(0.08f, 0.09f, 0.12f, 0.04f); viewport.AddComponent().showMaskGraphic = false; var content = new GameObject("Content"); content.transform.SetParent(viewport.transform, false); var contentRect = content.AddComponent(); contentRect.anchorMin = new Vector2(0f, 1f); contentRect.anchorMax = new Vector2(1f, 1f); contentRect.pivot = new Vector2(0.5f, 1f); contentRect.offsetMin = new Vector2(16f, 0f); contentRect.offsetMax = new Vector2(-16f, 0f); var layout = content.AddComponent(); layout.padding = new RectOffset(0, 0, 12, 12); layout.spacing = 12f; layout.childControlHeight = true; layout.childControlWidth = true; layout.childForceExpandHeight = false; layout.childForceExpandWidth = true; content.AddComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize; scrollRect.viewport = viewportRect; scrollRect.content = contentRect; context.inventoryContentRoot = content.transform; context.inventoryEmptyText = CreateText( "EmptyInventoryText", content.transform, "Пока что здесь пусто. Найдите записки на уровне.", assets.font, 24, TextAnchor.MiddleCenter, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(12f, -20f), new Vector2(-12f, 40f), new Color(0.86f, 0.87f, 0.91f)); SetVerticalLayoutItem(context.inventoryEmptyText.gameObject, 96f); context.inventoryButtonTemplate = CreateButton( "InventoryNoteButtonTemplate", content.transform, "Записка", assets, new Vector2(0f, 1f), new Vector2(1f, 1f), Vector2.zero, new Vector2(0f, 56f), new Color(0.12f, 0.28f, 0.42f, 1f)); ConfigureLayoutButton(context.inventoryButtonTemplate, 56f); context.inventoryButtonTemplate.gameObject.SetActive(false); } private static void CreateNotePanel(Transform parent, BuilderAssets assets, UIContext context) { var panel = CreatePanel( "NotePanel", parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(760f, 620f), new Color(0.16f, 0.15f, 0.12f, 0.97f), null); context.notePanel = panel; panel.SetActive(false); context.noteTitleText = CreateText( "NoteTitle", panel.transform, "Заголовок", assets.font, 36, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(28f, -22f), new Vector2(-180f, 58f), new Color(1f, 0.96f, 0.86f)); context.noteCloseButton = CreateButton( "CloseNoteButton", panel.transform, "Закрыть", assets, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-30f, -26f), new Vector2(150f, 50f), new Color(0.48f, 0.22f, 0.18f, 1f)); var bodyPanel = CreatePanel( "NoteBody", panel.transform, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(0.5f, 0.5f), new Vector2(0f, -30f), new Vector2(-50f, -120f), new Color(0.94f, 0.9f, 0.76f, 0.98f), null); context.noteContentText = CreateText( "NoteContent", bodyPanel.transform, "Текст записки", assets.font, 26, TextAnchor.UpperLeft, new Vector2(0f, 0f), new Vector2(1f, 1f), new Vector2(20f, -20f), new Vector2(-40f, -40f), new Color(0.16f, 0.13f, 0.09f)); context.noteContentText.horizontalOverflow = HorizontalWrapMode.Wrap; context.noteContentText.verticalOverflow = VerticalWrapMode.Overflow; } private static void CreateDialoguePanel(Transform parent, BuilderAssets assets, UIContext context) { var panel = CreatePanel( "DialoguePanel", parent, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 24f), new Vector2(960f, 330f), new Color(0.08f, 0.1f, 0.12f, 0.95f), null); context.dialoguePanel = panel; panel.SetActive(false); context.dialogueNameText = CreateText( "DialogueName", panel.transform, "NPC", assets.font, 32, TextAnchor.MiddleLeft, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(26f, -20f), new Vector2(-180f, 52f), new Color(0.73f, 0.89f, 1f)); context.dialogueCloseButton = CreateButton( "CloseDialogueButton", panel.transform, "Закрыть", assets, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-28f, -24f), new Vector2(150f, 48f), new Color(0.47f, 0.22f, 0.18f, 1f)); context.dialogueBodyText = CreateText( "DialogueBody", panel.transform, "Текст диалога", assets.font, 26, TextAnchor.UpperLeft, new Vector2(0f, 0.46f), new Vector2(1f, 0.86f), new Vector2(26f, -10f), new Vector2(-52f, -12f), Color.white); var optionsRoot = new GameObject("OptionsRoot"); optionsRoot.transform.SetParent(panel.transform, false); var optionsRect = optionsRoot.AddComponent(); optionsRect.anchorMin = new Vector2(0f, 0f); optionsRect.anchorMax = new Vector2(1f, 0.42f); optionsRect.offsetMin = new Vector2(26f, 22f); optionsRect.offsetMax = new Vector2(-26f, -10f); var optionsLayout = optionsRoot.AddComponent(); optionsLayout.padding = new RectOffset(0, 0, 8, 8); optionsLayout.spacing = 10f; optionsLayout.childControlHeight = true; optionsLayout.childControlWidth = true; optionsLayout.childForceExpandHeight = false; optionsLayout.childForceExpandWidth = true; optionsRoot.AddComponent().verticalFit = ContentSizeFitter.FitMode.PreferredSize; context.dialogueOptionsRoot = optionsRoot.transform; context.dialogueOptionTemplate = CreateButton( "DialogueOptionTemplate", optionsRoot.transform, "Ответ игрока", assets, new Vector2(0f, 1f), new Vector2(1f, 1f), Vector2.zero, new Vector2(0f, 54f), new Color(0.11f, 0.3f, 0.39f, 1f)); ConfigureLayoutButton(context.dialogueOptionTemplate, 54f); context.dialogueOptionTemplate.gameObject.SetActive(false); } private static void CreateInteractionPrompt(Transform parent, BuilderAssets assets, UIContext context) { var panel = CreatePanel( "InteractionPrompt", parent, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 170f), new Vector2(280f, 60f), new Color(0.94f, 0.8f, 0.18f, 0.95f), null); context.promptPanel = panel; panel.SetActive(false); context.promptText = CreateText( "PromptText", panel.transform, "Нажмите E", assets.font, 28, TextAnchor.MiddleCenter, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero, new Color(0.18f, 0.14f, 0.06f)); } private static void CreateQuestCompletePanel(Transform parent, BuilderAssets assets, UIContext context) { var panel = CreatePanel( "QuestCompletePanel", parent, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -30f), new Vector2(440f, 100f), new Color(0.18f, 0.42f, 0.22f, 0.92f), null); context.questCompletePanel = panel; panel.SetActive(false); context.questCompleteText = CreateText( "QuestCompleteText", panel.transform, "Квест выполнен!", assets.font, 32, TextAnchor.MiddleCenter, Vector2.zero, Vector2.one, Vector2.zero, Vector2.zero, Color.white); var levelPanel = CreatePanel( "LevelCompletePanel", parent, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(760f, 220f), new Color(0.08f, 0.1f, 0.14f, 0.94f), null); context.levelCompletePanel = levelPanel; levelPanel.SetActive(false); context.levelCompleteText = CreateText( "LevelCompleteText", levelPanel.transform, "Уровень завершен!", assets.font, 38, TextAnchor.MiddleCenter, Vector2.zero, Vector2.one, new Vector2(30f, 30f), new Vector2(-30f, -30f), Color.white); } private static void CreateEventSystem(Transform parent) { var eventSystem = new GameObject("EventSystem"); eventSystem.transform.SetParent(parent); eventSystem.AddComponent(); eventSystem.AddComponent(); } private static void CreateGameSystems(Transform parent, UIContext ui, GameObject exitDoor, GameObject exitTrigger) { var systems = new GameObject("GameSystems"); systems.transform.SetParent(parent); var prompt = systems.AddComponent(); prompt.Configure(ui.promptPanel, ui.promptText); var noteUI = systems.AddComponent(); noteUI.Configure(ui.notePanel, ui.noteTitleText, ui.noteContentText, ui.noteCloseButton); var inventory = systems.AddComponent(); inventory.Configure( ui.inventoryPanel, ui.inventoryContentRoot, ui.inventoryButtonTemplate, ui.inventoryEmptyText, ui.inventoryCloseButton); var dialogueUI = systems.AddComponent(); dialogueUI.Configure( ui.dialoguePanel, ui.dialogueNameText, ui.dialogueBodyText, ui.dialogueOptionsRoot, ui.dialogueOptionTemplate, ui.dialogueCloseButton); var questManager = systems.AddComponent(); questManager.Configure( ui.questStatusText, ui.questCompletePanel, ui.questCompleteText, exitDoor, exitTrigger, ui.levelCompletePanel, ui.levelCompleteText, 3); } private static void CreatePlayer(Transform parent) { var player = GameObject.CreatePrimitive(PrimitiveType.Capsule); player.name = "Player"; player.transform.SetParent(parent); player.transform.position = new Vector3(-9f, 0.1f, -9f); player.tag = "Player"; var renderer = player.GetComponent(); if (renderer != null) { renderer.enabled = false; } var primitiveCollider = player.GetComponent(); if (primitiveCollider != null) { Object.DestroyImmediate(primitiveCollider); } var controller = player.AddComponent(); controller.center = new Vector3(0f, 1f, 0f); controller.height = 2f; controller.radius = 0.35f; controller.stepOffset = 0.3f; var cameraObject = new GameObject("PlayerCamera"); cameraObject.transform.SetParent(player.transform); cameraObject.transform.localPosition = new Vector3(0f, 1.6f, 0f); cameraObject.transform.localRotation = Quaternion.identity; var camera = cameraObject.AddComponent(); camera.fieldOfView = 70f; camera.nearClipPlane = 0.01f; camera.farClipPlane = 100f; cameraObject.AddComponent(); var controllerScript = player.AddComponent(); controllerScript.Configure(camera); } private static void CreateNotes(Transform parent, BuilderAssets assets) { var notesRoot = new GameObject("Notes"); notesRoot.transform.SetParent(parent); CreateNote( notesRoot.transform, "Записка 1", "Вчерашняя разведка подтверждает: в архивах спрятаны три части истории этого места.", new Vector3(-8f, 1.05f, 8f), assets.noteMaterial, assets.highlightMaterial); CreateNote( notesRoot.transform, "Записка 2", "Смотритель знает больше, чем говорит. Но он заговорит только после того, как увидит найденные записи.", new Vector3(3.2f, 1.35f, -4.8f), assets.noteMaterial, assets.highlightMaterial); CreateNote( notesRoot.transform, "Записка 3", "Если собрать все фрагменты и поговорить со смотрителем, путь к выходу из сектора откроется.", new Vector3(8.5f, 1.7f, 9.6f), assets.noteMaterial, assets.highlightMaterial); } private static void CreateNpc(Transform parent, BuilderAssets assets) { var npcRoot = new GameObject("NPC_Smotritel"); npcRoot.transform.SetParent(parent); npcRoot.transform.position = new Vector3(8.5f, 0f, -8.5f); var body = GameObject.CreatePrimitive(PrimitiveType.Capsule); body.name = "Body"; body.transform.SetParent(npcRoot.transform); body.transform.localPosition = new Vector3(0f, 1f, 0f); body.transform.localRotation = Quaternion.identity; body.transform.localScale = new Vector3(1f, 1f, 1f); var bodyRenderer = body.GetComponent(); bodyRenderer.sharedMaterial = assets.npcMaterial; var npc = npcRoot.AddComponent(); npc.Configure( "Смотритель", "Ты уже собрал все улики? Мне нужно понять, можно ли тебе доверять.", bodyRenderer, assets.npcMaterial, assets.highlightMaterial, new List { new NPC.DialogueOption { playerReply = "Я собрал все записки. Что теперь?", npcReply = "Теперь всё ясно. История восстановлена, а дверь к выходу больше не должна тебя удерживать.", closeAfterSelection = false, requiresAllNotes = true, unavailableReply = "Нет, ты ещё не собрал все записки. Вернись, когда восстановишь всю историю." }, new NPC.DialogueOption { playerReply = "Пока просто осматриваюсь.", npcReply = string.Empty, closeAfterSelection = true } }); var triggerObject = new GameObject("InteractionTrigger"); triggerObject.transform.SetParent(npcRoot.transform); triggerObject.transform.localPosition = new Vector3(0f, 1.1f, 0f); var sphereCollider = triggerObject.AddComponent(); sphereCollider.isTrigger = true; sphereCollider.radius = 2.4f; var triggerRelay = triggerObject.AddComponent(); triggerRelay.Initialize(npc); } private static void CreateNote( Transform parent, string title, string content, Vector3 position, Material noteMaterial, Material highlightMaterial) { var noteRoot = new GameObject(title); noteRoot.transform.SetParent(parent); noteRoot.transform.position = position; var boxCollider = noteRoot.AddComponent(); boxCollider.isTrigger = true; boxCollider.size = new Vector3(2.2f, 1.4f, 2.2f); boxCollider.center = new Vector3(0f, 0.35f, 0f); var visual = GameObject.CreatePrimitive(PrimitiveType.Cube); visual.name = "Visual"; visual.transform.SetParent(noteRoot.transform); visual.transform.localPosition = new Vector3(0f, 0f, 0f); visual.transform.localScale = new Vector3(0.55f, 0.06f, 0.75f); var visualCollider = visual.GetComponent(); if (visualCollider != null) { Object.DestroyImmediate(visualCollider); } var renderer = visual.GetComponent(); renderer.sharedMaterial = noteMaterial; var note = noteRoot.AddComponent(); note.Configure(title, content, renderer, noteMaterial, highlightMaterial); } private static void CreateTable(Transform parent, Vector3 position, Material material) { var tableRoot = new GameObject("Table"); tableRoot.transform.SetParent(parent); tableRoot.transform.position = position; CreateCube("Top", tableRoot.transform, new Vector3(0f, 0.95f, 0f), new Vector3(2f, 0.12f, 1.2f), material); CreateCube("Leg_A", tableRoot.transform, new Vector3(-0.8f, 0.45f, -0.45f), new Vector3(0.12f, 0.9f, 0.12f), material); CreateCube("Leg_B", tableRoot.transform, new Vector3(0.8f, 0.45f, -0.45f), new Vector3(0.12f, 0.9f, 0.12f), material); CreateCube("Leg_C", tableRoot.transform, new Vector3(-0.8f, 0.45f, 0.45f), new Vector3(0.12f, 0.9f, 0.12f), material); CreateCube("Leg_D", tableRoot.transform, new Vector3(0.8f, 0.45f, 0.45f), new Vector3(0.12f, 0.9f, 0.12f), material); } private static void CreateCrate(Transform parent, Vector3 position, Vector3 scale, Material material) { CreateCube("Crate", parent, position, scale, material); } private static void CreateShelf(Transform parent, Vector3 position, Material woodMaterial, Material fillMaterial) { var shelfRoot = new GameObject("Shelf"); shelfRoot.transform.SetParent(parent); shelfRoot.transform.position = position; CreateCube("Side_Left", shelfRoot.transform, new Vector3(-0.8f, 1.2f, 0f), new Vector3(0.14f, 2.4f, 0.6f), woodMaterial); CreateCube("Side_Right", shelfRoot.transform, new Vector3(0.8f, 1.2f, 0f), new Vector3(0.14f, 2.4f, 0.6f), woodMaterial); CreateCube("Top", shelfRoot.transform, new Vector3(0f, 2.35f, 0f), new Vector3(1.8f, 0.14f, 0.6f), woodMaterial); CreateCube("Bottom", shelfRoot.transform, new Vector3(0f, 0.15f, 0f), new Vector3(1.8f, 0.14f, 0.6f), woodMaterial); CreateCube("Middle_1", shelfRoot.transform, new Vector3(0f, 0.85f, 0f), new Vector3(1.8f, 0.1f, 0.6f), woodMaterial); CreateCube("Middle_2", shelfRoot.transform, new Vector3(0f, 1.55f, 0f), new Vector3(1.8f, 0.1f, 0.6f), woodMaterial); CreateCube("Storage", shelfRoot.transform, new Vector3(0f, 1.2f, -0.2f), new Vector3(1.45f, 2f, 0.12f), fillMaterial); } private static void CreateBench(Transform parent, Vector3 position, Material material) { var benchRoot = new GameObject("Bench"); benchRoot.transform.SetParent(parent); benchRoot.transform.position = position; CreateCube("Seat", benchRoot.transform, new Vector3(0f, 0.55f, 0f), new Vector3(2.2f, 0.14f, 0.65f), material); CreateCube("Leg_A", benchRoot.transform, new Vector3(-0.9f, 0.25f, 0f), new Vector3(0.12f, 0.5f, 0.12f), material); CreateCube("Leg_B", benchRoot.transform, new Vector3(0.9f, 0.25f, 0f), new Vector3(0.12f, 0.5f, 0.12f), material); } private static void CreateColumn(Transform parent, Vector3 position, Material material) { CreateCube("Column", parent, position, new Vector3(0.8f, 3f, 0.8f), material); } private static GameObject CreatePlane(string name, Transform parent, Vector3 position, Vector3 scale, Material material) { var plane = GameObject.CreatePrimitive(PrimitiveType.Plane); plane.name = name; plane.transform.SetParent(parent); plane.transform.position = position; plane.transform.localScale = scale; plane.GetComponent().sharedMaterial = material; return plane; } private static GameObject CreateCube(string name, Transform parent, Vector3 position, Vector3 scale, Material material) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.name = name; cube.transform.SetParent(parent); cube.transform.localPosition = position; cube.transform.localScale = scale; cube.GetComponent().sharedMaterial = material; return cube; } private static GameObject CreateSphere(string name, Transform parent, Vector3 position, Vector3 scale, Material material) { var sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.name = name; sphere.transform.SetParent(parent); sphere.transform.localPosition = position; sphere.transform.localScale = scale; sphere.GetComponent().sharedMaterial = material; return sphere; } private static GameObject CreatePanel( string name, Transform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPosition, Vector2 sizeDelta, Color color, Sprite sprite) { var panel = new GameObject(name); panel.transform.SetParent(parent, false); var rectTransform = panel.AddComponent(); rectTransform.anchorMin = anchorMin; rectTransform.anchorMax = anchorMax; rectTransform.pivot = pivot; rectTransform.anchoredPosition = anchoredPosition; rectTransform.sizeDelta = sizeDelta; var image = panel.AddComponent(); image.sprite = sprite; image.type = Image.Type.Simple; image.color = color; return panel; } private static Text CreateText( string name, Transform parent, string value, Font font, int fontSize, TextAnchor alignment, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax, Color color) { var textObject = new GameObject(name); textObject.transform.SetParent(parent, false); var rectTransform = textObject.AddComponent(); rectTransform.anchorMin = anchorMin; rectTransform.anchorMax = anchorMax; rectTransform.offsetMin = offsetMin; rectTransform.offsetMax = offsetMax; var text = textObject.AddComponent(); text.font = font; text.text = value; text.fontSize = fontSize; text.alignment = alignment; text.color = color; text.supportRichText = true; text.horizontalOverflow = HorizontalWrapMode.Wrap; text.verticalOverflow = VerticalWrapMode.Truncate; return text; } private static Button CreateButton( string name, Transform parent, string label, BuilderAssets assets, Vector2 anchorMin, Vector2 anchorMax, Vector2 anchoredPosition, Vector2 sizeDelta, Color color) { var buttonObject = new GameObject(name); buttonObject.transform.SetParent(parent, false); var rectTransform = buttonObject.AddComponent(); rectTransform.anchorMin = anchorMin; rectTransform.anchorMax = anchorMax; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = anchoredPosition; rectTransform.sizeDelta = sizeDelta; var image = buttonObject.AddComponent(); image.sprite = null; image.type = Image.Type.Simple; image.color = color; var button = buttonObject.AddComponent