From 5081d01aa453236ed0e2d94c6a2864045281ec28 Mon Sep 17 00:00:00 2001 From: Dmitry Evdokimov Date: Mon, 25 May 2026 23:53:50 +0300 Subject: [PATCH] first commit --- .gitignore | 58 + Assets/Editor.meta | 8 + Assets/Editor/Lab4SceneBuilder.cs | 1147 ++ Assets/Editor/Lab4SceneBuilder.cs.meta | 11 + Assets/Materials.meta | 8 + Assets/Materials/Lab4.meta | 8 + Assets/Materials/Lab4/Accent.mat | 83 + Assets/Materials/Lab4/Accent.mat.meta | 8 + Assets/Materials/Lab4/Decor.mat | 83 + Assets/Materials/Lab4/Decor.mat.meta | 8 + Assets/Materials/Lab4/Door.mat | 83 + Assets/Materials/Lab4/Door.mat.meta | 8 + Assets/Materials/Lab4/Floor.mat | 83 + Assets/Materials/Lab4/Floor.mat.meta | 8 + Assets/Materials/Lab4/Highlight.mat | 83 + Assets/Materials/Lab4/Highlight.mat.meta | 8 + Assets/Materials/Lab4/NPC.mat | 83 + Assets/Materials/Lab4/NPC.mat.meta | 8 + Assets/Materials/Lab4/Note.mat | 83 + Assets/Materials/Lab4/Note.mat.meta | 8 + Assets/Materials/Lab4/Wall.mat | 83 + Assets/Materials/Lab4/Wall.mat.meta | 8 + Assets/Materials/Lab4/Wood.mat | 83 + Assets/Materials/Lab4/Wood.mat.meta | 8 + Assets/Scenes.meta | 8 + Assets/Scenes/Lab4_NarrativeExploration.unity | 11211 ++++++++++++++++ .../Lab4_NarrativeExploration.unity.meta | 7 + Assets/Scripts.meta | 8 + Assets/Scripts/DialogueUI.cs | 163 + Assets/Scripts/DialogueUI.cs.meta | 11 + Assets/Scripts/GameUIState.cs | 53 + Assets/Scripts/GameUIState.cs.meta | 11 + Assets/Scripts/InteractionPromptUI.cs | 110 + Assets/Scripts/InteractionPromptUI.cs.meta | 11 + Assets/Scripts/Inventory.cs | 178 + Assets/Scripts/Inventory.cs.meta | 11 + Assets/Scripts/LevelExitTrigger.cs | 14 + Assets/Scripts/LevelExitTrigger.cs.meta | 11 + Assets/Scripts/NPC.cs | 162 + Assets/Scripts/NPC.cs.meta | 11 + Assets/Scripts/NPCTriggerRelay.cs | 27 + Assets/Scripts/NPCTriggerRelay.cs.meta | 11 + Assets/Scripts/Note.cs | 117 + Assets/Scripts/Note.cs.meta | 11 + Assets/Scripts/NoteData.cs | 18 + Assets/Scripts/NoteData.cs.meta | 11 + Assets/Scripts/NoteUI.cs | 80 + Assets/Scripts/NoteUI.cs.meta | 11 + Assets/Scripts/QuestManager.cs | 186 + Assets/Scripts/QuestManager.cs.meta | 11 + Assets/Scripts/SimpleFPSController.cs | 97 + Assets/Scripts/SimpleFPSController.cs.meta | 11 + Packages/manifest.json | 41 + Packages/packages-lock.json | 382 + ProjectSettings/AudioManager.asset | 19 + ProjectSettings/ClusterInputManager.asset | 6 + ProjectSettings/DynamicsManager.asset | 34 + ProjectSettings/EditorBuildSettings.asset | 8 + ProjectSettings/EditorSettings.asset | 30 + ProjectSettings/GraphicsSettings.asset | 63 + ProjectSettings/InputManager.asset | 295 + ProjectSettings/MemorySettings.asset | 35 + ProjectSettings/NavMeshAreas.asset | 91 + ProjectSettings/PackageManagerSettings.asset | 35 + .../Settings.json | 5 + ProjectSettings/Physics2DSettings.asset | 56 + ProjectSettings/PresetManager.asset | 7 + ProjectSettings/ProjectSettings.asset | 772 ++ ProjectSettings/ProjectVersion.txt | 2 + ProjectSettings/QualitySettings.asset | 234 + ProjectSettings/SceneTemplateSettings.json | 121 + ProjectSettings/TagManager.asset | 44 + ProjectSettings/TimeManager.asset | 9 + ProjectSettings/UnityConnectSettings.asset | 36 + ProjectSettings/VFXManager.asset | 12 + ProjectSettings/VersionControlSettings.asset | 8 + ProjectSettings/XRSettings.asset | 10 + 77 files changed, 16985 insertions(+) create mode 100644 .gitignore create mode 100644 Assets/Editor.meta create mode 100644 Assets/Editor/Lab4SceneBuilder.cs create mode 100644 Assets/Editor/Lab4SceneBuilder.cs.meta create mode 100644 Assets/Materials.meta create mode 100644 Assets/Materials/Lab4.meta create mode 100644 Assets/Materials/Lab4/Accent.mat create mode 100644 Assets/Materials/Lab4/Accent.mat.meta create mode 100644 Assets/Materials/Lab4/Decor.mat create mode 100644 Assets/Materials/Lab4/Decor.mat.meta create mode 100644 Assets/Materials/Lab4/Door.mat create mode 100644 Assets/Materials/Lab4/Door.mat.meta create mode 100644 Assets/Materials/Lab4/Floor.mat create mode 100644 Assets/Materials/Lab4/Floor.mat.meta create mode 100644 Assets/Materials/Lab4/Highlight.mat create mode 100644 Assets/Materials/Lab4/Highlight.mat.meta create mode 100644 Assets/Materials/Lab4/NPC.mat create mode 100644 Assets/Materials/Lab4/NPC.mat.meta create mode 100644 Assets/Materials/Lab4/Note.mat create mode 100644 Assets/Materials/Lab4/Note.mat.meta create mode 100644 Assets/Materials/Lab4/Wall.mat create mode 100644 Assets/Materials/Lab4/Wall.mat.meta create mode 100644 Assets/Materials/Lab4/Wood.mat create mode 100644 Assets/Materials/Lab4/Wood.mat.meta create mode 100644 Assets/Scenes.meta create mode 100644 Assets/Scenes/Lab4_NarrativeExploration.unity create mode 100644 Assets/Scenes/Lab4_NarrativeExploration.unity.meta create mode 100644 Assets/Scripts.meta create mode 100644 Assets/Scripts/DialogueUI.cs create mode 100644 Assets/Scripts/DialogueUI.cs.meta create mode 100644 Assets/Scripts/GameUIState.cs create mode 100644 Assets/Scripts/GameUIState.cs.meta create mode 100644 Assets/Scripts/InteractionPromptUI.cs create mode 100644 Assets/Scripts/InteractionPromptUI.cs.meta create mode 100644 Assets/Scripts/Inventory.cs create mode 100644 Assets/Scripts/Inventory.cs.meta create mode 100644 Assets/Scripts/LevelExitTrigger.cs create mode 100644 Assets/Scripts/LevelExitTrigger.cs.meta create mode 100644 Assets/Scripts/NPC.cs create mode 100644 Assets/Scripts/NPC.cs.meta create mode 100644 Assets/Scripts/NPCTriggerRelay.cs create mode 100644 Assets/Scripts/NPCTriggerRelay.cs.meta create mode 100644 Assets/Scripts/Note.cs create mode 100644 Assets/Scripts/Note.cs.meta create mode 100644 Assets/Scripts/NoteData.cs create mode 100644 Assets/Scripts/NoteData.cs.meta create mode 100644 Assets/Scripts/NoteUI.cs create mode 100644 Assets/Scripts/NoteUI.cs.meta create mode 100644 Assets/Scripts/QuestManager.cs create mode 100644 Assets/Scripts/QuestManager.cs.meta create mode 100644 Assets/Scripts/SimpleFPSController.cs create mode 100644 Assets/Scripts/SimpleFPSController.cs.meta create mode 100644 Packages/manifest.json create mode 100644 Packages/packages-lock.json create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/MemorySettings.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/PackageManagerSettings.asset create mode 100644 ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/PresetManager.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/SceneTemplateSettings.json create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 ProjectSettings/VFXManager.asset create mode 100644 ProjectSettings/VersionControlSettings.asset create mode 100644 ProjectSettings/XRSettings.asset diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc2223f --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +# Unity generated folders +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +[Ll]ogs/ +[Uu]ser[Ss]ettings/ +[Mm]emoryCaptures/ +[Rr]ecordings/ +generate_lab4_protocol.py +Lab4_Protocol.docx +# Unity generated files +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Auto-generated IDE / editor settings +.vs/ +.idea/ +.fleet/ +.vscode/ + +# Python virtual environments and caches +.venv/ +venv/ +__pycache__/ +*.pyc + +# OS / misc temp files +.DS_Store +Thumbs.db +*.swp +*.bak +*~ + +# Office / lock / temporary files +~$* +.~lock.* +.xdp-* + +# Optional generated artifacts +*.apk +*.aab +*.app +*.exe +*.ipa diff --git a/Assets/Editor.meta b/Assets/Editor.meta new file mode 100644 index 0000000..5367e0c --- /dev/null +++ b/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c962c7f033cd2ac79854a267c6b6cb5c +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Lab4SceneBuilder.cs b/Assets/Editor/Lab4SceneBuilder.cs new file mode 100644 index 0000000..dd8fbea --- /dev/null +++ b/Assets/Editor/Lab4SceneBuilder.cs @@ -0,0 +1,1147 @@ +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