using System.Collections.Generic; using System.IO; using UnityEditor; using UnityEditor.SceneManagement; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.SceneManagement; using UnityEngine.UI; public static class Lab3SceneBuilder { private const string ScriptsPath = "Assets/_Scripts"; private const string DataPath = "Assets/_Data"; private const string ItemsPath = "Assets/_Data/Items"; private const string RecipesPath = "Assets/_Data/Recipes"; private const string PrefabsPath = "Assets/_Prefabs"; private const string ScenesPath = "Assets/_Scenes"; private const string MaterialsPath = "Assets/_Materials"; private const string FontsPath = "Assets/_Fonts"; private const string EditorPath = "Assets/Editor"; private const string ScenePath = "Assets/_Scenes/Lab03_CraftingSystem.unity"; private const string RegularFontPath = "Assets/_Fonts/Ubuntu-Regular.ttf"; private const string BoldFontPath = "Assets/_Fonts/Ubuntu-Bold.ttf"; [MenuItem("Tools/Technical Game Design/Lab3/Create Crafting System Scene")] public static void CreateCraftingSystemScene() { CreateFolders(); Font uiFont = InstallUbuntuFont(); Dictionary materials = CreateMaterials(); Dictionary items = CreateItems(); List recipes = CreateRecipes(items); GameObject recipeButtonPrefab = CreateRecipeButtonPrefab(uiFont); GameObject slotPrefab = CreateInventorySlotPrefab(uiFont); GameObject hotbarSlotPrefab = CreateHotbarSlotPrefab(uiFont); Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); scene.name = "Lab03_CraftingSystem"; CreateWorld(materials, items, uiFont); CreateCameraAndLight(); CreateSystems(items, recipes, materials, uiFont, recipeButtonPrefab, slotPrefab, hotbarSlotPrefab); EditorSceneManager.SaveScene(scene, ScenePath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); Debug.Log("Lab03 Crafting System scene created: " + ScenePath); } private static void CreateFolders() { string[] folders = { ScriptsPath, DataPath, ItemsPath, RecipesPath, PrefabsPath, ScenesPath, MaterialsPath, FontsPath, EditorPath }; for (int i = 0; i < folders.Length; i++) { if (!AssetDatabase.IsValidFolder(folders[i])) { Directory.CreateDirectory(folders[i]); } } AssetDatabase.Refresh(); } private static Font InstallUbuntuFont() { string regularSource = FindFontFile(new[] { "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", "/usr/share/fonts/truetype/ubuntu/Ubuntu-Regular.ttf", "/usr/share/fonts/TTF/Ubuntu-R.ttf", "/usr/share/fonts/TTF/Ubuntu-Regular.ttf" }, "Ubuntu-R*.ttf", "Ubuntu-Regular*.ttf"); string boldSource = FindFontFile(new[] { "/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", "/usr/share/fonts/truetype/ubuntu/Ubuntu-Bold.ttf", "/usr/share/fonts/TTF/Ubuntu-B.ttf", "/usr/share/fonts/TTF/Ubuntu-Bold.ttf" }, "Ubuntu-B*.ttf", "Ubuntu-Bold*.ttf"); if (!string.IsNullOrEmpty(regularSource)) { File.Copy(regularSource, RegularFontPath, true); AssetDatabase.ImportAsset(RegularFontPath); Debug.Log("Ubuntu regular font copied to " + RegularFontPath); } else { Debug.LogWarning("Ubuntu regular font was not found in system font folders. UI will use built-in Arial fallback."); } if (!string.IsNullOrEmpty(boldSource)) { File.Copy(boldSource, BoldFontPath, true); AssetDatabase.ImportAsset(BoldFontPath); Debug.Log("Ubuntu bold font copied to " + BoldFontPath); } AssetDatabase.Refresh(); Font font = AssetDatabase.LoadAssetAtPath(RegularFontPath); return font != null ? font : Resources.GetBuiltinResource("LegacyRuntime.ttf"); } private static string FindFontFile(string[] preferredPaths, params string[] patterns) { for (int i = 0; i < preferredPaths.Length; i++) { if (File.Exists(preferredPaths[i])) { return preferredPaths[i]; } } string[] roots = { "/usr/share/fonts/truetype/ubuntu", "/usr/share/fonts/TTF", "/usr/share/fonts" }; for (int i = 0; i < roots.Length; i++) { if (!Directory.Exists(roots[i])) { continue; } for (int p = 0; p < patterns.Length; p++) { string[] files = Directory.GetFiles(roots[i], patterns[p], SearchOption.AllDirectories); if (files.Length > 0) { return files[0]; } } } return null; } private static Dictionary CreateMaterials() { Dictionary materialColors = new Dictionary { { "Mat_Floor", new Color(0.36f, 0.42f, 0.36f) }, { "Mat_Workbench", new Color(0.42f, 0.25f, 0.12f) }, { "Mat_Workbench_Dark", new Color(0.22f, 0.13f, 0.07f) }, { "Mat_Wood", new Color(0.55f, 0.34f, 0.16f) }, { "Mat_Stone", new Color(0.47f, 0.48f, 0.47f) }, { "Mat_Iron", new Color(0.55f, 0.58f, 0.62f) }, { "Mat_Fiber", new Color(0.48f, 0.66f, 0.34f) }, { "Mat_Coal", new Color(0.05f, 0.05f, 0.05f) }, { "Mat_Herb", new Color(0.18f, 0.62f, 0.25f) }, { "Mat_Crystal", new Color(0.35f, 0.78f, 0.95f) }, { "Mat_Player", new Color(0.20f, 0.44f, 0.82f) }, { "Mat_Torch_Light", new Color(1.00f, 0.55f, 0.12f) } }; Dictionary result = new Dictionary(); foreach (KeyValuePair pair in materialColors) { string path = MaterialsPath + "/" + pair.Key + ".mat"; Material material = AssetDatabase.LoadAssetAtPath(path); if (material == null) { material = new Material(Shader.Find("Standard")); AssetDatabase.CreateAsset(material, path); } material.color = pair.Value; EditorUtility.SetDirty(material); result[pair.Key] = material; } return result; } private static Dictionary CreateItems() { ItemDefinition[] definitions = { new ItemDefinition("Wood", "wood", "Древесина", "Базовый строительный ресурс для рукоятей и простых инструментов.", 64, true, new Color(0.58f, 0.36f, 0.16f)), new ItemDefinition("Stone", "stone", "Камень", "Твердый ресурс для лезвий и ударных частей инструментов.", 64, true, new Color(0.55f, 0.55f, 0.55f)), new ItemDefinition("Stick", "stick", "Палка", "Готовая рукоять для простых рецептов.", 64, true, new Color(0.64f, 0.42f, 0.20f)), new ItemDefinition("IronOre", "iron_ore", "Железная руда", "Металлическое сырье для прочных инструментов.", 64, true, new Color(0.56f, 0.58f, 0.64f)), new ItemDefinition("Fiber", "fiber", "Волокно", "Гибкий материал для перевязки и связки деталей.", 64, true, new Color(0.72f, 0.78f, 0.48f)), new ItemDefinition("Leather", "leather", "Кожа", "Прочный материал для креплений и украшений.", 32, true, new Color(0.45f, 0.25f, 0.12f)), new ItemDefinition("Coal", "coal", "Уголь", "Горючий ресурс для факелов.", 64, true, new Color(0.08f, 0.08f, 0.08f)), new ItemDefinition("Herb", "herb", "Трава", "Лечебное растение для простых расходников.", 64, true, new Color(0.20f, 0.66f, 0.24f)), new ItemDefinition("Crystal", "crystal", "Кристалл", "Редкий магический ресурс.", 16, true, new Color(0.30f, 0.80f, 1.00f)), new ItemDefinition("Axe", "axe", "Топор", "Инструмент для рубки древесины.", 1, false, new Color(0.76f, 0.72f, 0.62f)), new ItemDefinition("Pickaxe", "pickaxe", "Кирка", "Инструмент для добычи камня и руды.", 1, false, new Color(0.65f, 0.68f, 0.72f)), new ItemDefinition("Torch", "torch", "Факел", "Источник света, создается по две штуки за крафт.", 16, false, new Color(1.00f, 0.62f, 0.18f)), new ItemDefinition("Bandage", "bandage", "Бинт", "Расходный предмет для восстановления здоровья.", 16, false, new Color(0.92f, 0.90f, 0.82f)), new ItemDefinition("MagicAmulet", "magic_amulet", "Магический амулет", "Редкий предмет, усиливающий героя.", 1, false, new Color(0.55f, 0.35f, 0.95f)) }; Dictionary items = new Dictionary(); for (int i = 0; i < definitions.Length; i++) { ItemDefinition definition = definitions[i]; string path = ItemsPath + "/" + definition.assetName + ".asset"; ItemData item = AssetDatabase.LoadAssetAtPath(path); if (item == null) { item = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(item, path); } item.itemId = definition.itemId; item.itemName = definition.itemName; item.description = definition.description; item.maxStack = definition.maxStack; item.isResource = definition.isResource; item.itemColor = definition.itemColor; item.icon = null; EditorUtility.SetDirty(item); items[definition.assetName] = item; } AssetDatabase.SaveAssets(); return items; } private static List CreateRecipes(Dictionary items) { RecipeDefinition[] definitions = { new RecipeDefinition("Recipe_Axe", "recipe_axe", "Топор", "Простой топор из древесины, палки и камня.", "Axe", 1, new[] { Pair("Wood", 2), Pair("Stick", 1), Pair("Stone", 1) }), new RecipeDefinition("Recipe_Pickaxe", "recipe_pickaxe", "Кирка", "Прочная кирка для добычи твердых ресурсов.", "Pickaxe", 1, new[] { Pair("Wood", 2), Pair("Stick", 2), Pair("IronOre", 2) }), new RecipeDefinition("Recipe_Torch", "recipe_torch", "Факел", "Два факела из палки, угля и волокна.", "Torch", 2, new[] { Pair("Stick", 1), Pair("Coal", 1), Pair("Fiber", 1) }), new RecipeDefinition("Recipe_Bandage", "recipe_bandage", "Бинт", "Простая лечебная повязка из волокна и травы.", "Bandage", 1, new[] { Pair("Fiber", 2), Pair("Herb", 1) }), new RecipeDefinition("Recipe_MagicAmulet", "recipe_magic_amulet", "Магический амулет", "Редкий амулет из кристаллов, кожи и железной руды.", "MagicAmulet", 1, new[] { Pair("Crystal", 2), Pair("Leather", 1), Pair("IronOre", 1) }) }; List recipes = new List(); for (int i = 0; i < definitions.Length; i++) { RecipeDefinition definition = definitions[i]; string path = RecipesPath + "/" + definition.assetName + ".asset"; RecipeData recipe = AssetDatabase.LoadAssetAtPath(path); if (recipe == null) { recipe = ScriptableObject.CreateInstance(); AssetDatabase.CreateAsset(recipe, path); } recipe.recipeId = definition.recipeId; recipe.recipeName = definition.recipeName; recipe.description = definition.description; recipe.result = items[definition.resultKey]; recipe.resultAmount = definition.resultAmount; recipe.unlockedByDefault = true; recipe.ingredients = new Ingredient[definition.ingredients.Length]; for (int ingredientIndex = 0; ingredientIndex < definition.ingredients.Length; ingredientIndex++) { RecipeIngredientDefinition ingredientDefinition = definition.ingredients[ingredientIndex]; recipe.ingredients[ingredientIndex] = new Ingredient { item = items[ingredientDefinition.itemKey], amount = ingredientDefinition.amount }; } EditorUtility.SetDirty(recipe); recipes.Add(recipe); } AssetDatabase.SaveAssets(); return recipes; } private static RecipeIngredientDefinition Pair(string itemKey, int amount) { return new RecipeIngredientDefinition(itemKey, amount); } private static void CreateWorld(Dictionary materials, Dictionary items, Font worldFont) { GameObject floor = GameObject.CreatePrimitive(PrimitiveType.Plane); floor.name = "Floor"; floor.transform.localScale = new Vector3(2.8f, 1f, 2.2f); SetMaterial(floor, materials["Mat_Floor"]); GameObject tableTop = GameObject.CreatePrimitive(PrimitiveType.Cube); tableTop.name = "Crafting Workbench"; tableTop.transform.position = new Vector3(0f, 0.65f, 3.2f); tableTop.transform.localScale = new Vector3(3.6f, 0.28f, 1.5f); SetMaterial(tableTop, materials["Mat_Workbench"]); CreateCube("Workbench Leg FL", new Vector3(-1.45f, 0.25f, 3.72f), new Vector3(0.22f, 0.55f, 0.22f), materials["Mat_Workbench_Dark"]); CreateCube("Workbench Leg FR", new Vector3(1.45f, 0.25f, 3.72f), new Vector3(0.22f, 0.55f, 0.22f), materials["Mat_Workbench_Dark"]); CreateCube("Workbench Leg BL", new Vector3(-1.45f, 0.25f, 2.68f), new Vector3(0.22f, 0.55f, 0.22f), materials["Mat_Workbench_Dark"]); CreateCube("Workbench Leg BR", new Vector3(1.45f, 0.25f, 2.68f), new Vector3(0.22f, 0.55f, 0.22f), materials["Mat_Workbench_Dark"]); CreateWorldLabel("Workbench Label", "Верстак: крафт через панель справа", new Vector3(0f, 1.25f, 3.2f), worldFont); CreatePickup("Wood Pickup A", items["Wood"], 2, PrimitiveType.Cube, new Vector3(-5.5f, 0.35f, -2.8f), new Vector3(0.55f, 0.28f, 0.28f), materials["Mat_Wood"], worldFont); CreatePickup("Wood Pickup B", items["Wood"], 3, PrimitiveType.Cube, new Vector3(-4.8f, 0.35f, 1.8f), new Vector3(0.55f, 0.28f, 0.28f), materials["Mat_Wood"], worldFont); CreatePickup("Stone Pickup", items["Stone"], 3, PrimitiveType.Sphere, new Vector3(-2.9f, 0.35f, -4.2f), new Vector3(0.48f, 0.34f, 0.48f), materials["Mat_Stone"], worldFont); CreatePickup("Stick Pickup", items["Stick"], 2, PrimitiveType.Cube, new Vector3(2.2f, 0.22f, -4.7f), new Vector3(0.75f, 0.14f, 0.14f), materials["Mat_Wood"], worldFont); CreatePickup("Iron Ore Pickup", items["IronOre"], 2, PrimitiveType.Sphere, new Vector3(5.1f, 0.35f, -2.0f), new Vector3(0.45f, 0.34f, 0.45f), materials["Mat_Iron"], worldFont); CreatePickup("Fiber Pickup", items["Fiber"], 3, PrimitiveType.Cube, new Vector3(-3.7f, 0.20f, 4.8f), new Vector3(0.6f, 0.12f, 0.3f), materials["Mat_Fiber"], worldFont); CreatePickup("Leather Pickup", items["Leather"], 1, PrimitiveType.Cube, new Vector3(4.4f, 0.22f, 3.8f), new Vector3(0.55f, 0.12f, 0.42f), materials["Mat_Workbench"], worldFont); CreatePickup("Coal Pickup", items["Coal"], 2, PrimitiveType.Sphere, new Vector3(5.6f, 0.30f, 1.1f), new Vector3(0.38f, 0.28f, 0.38f), materials["Mat_Coal"], worldFont); CreatePickup("Herb Pickup", items["Herb"], 2, PrimitiveType.Cube, new Vector3(-0.5f, 0.20f, -5.0f), new Vector3(0.45f, 0.12f, 0.45f), materials["Mat_Herb"], worldFont); CreatePickup("Crystal Pickup", items["Crystal"], 2, PrimitiveType.Cylinder, new Vector3(2.9f, 0.45f, 5.1f), new Vector3(0.24f, 0.55f, 0.24f), materials["Mat_Crystal"], worldFont); } private static void CreateCameraAndLight() { GameObject cameraObject = new GameObject("Main Camera"); Camera camera = cameraObject.AddComponent(); cameraObject.tag = "MainCamera"; cameraObject.transform.position = new Vector3(0f, 8f, -7f); cameraObject.transform.rotation = Quaternion.Euler(58f, 0f, 0f); camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = new Color(0.12f, 0.14f, 0.16f); camera.fieldOfView = 48f; GameObject lightObject = new GameObject("Directional Light"); Light light = lightObject.AddComponent(); light.type = LightType.Directional; light.intensity = 1.05f; lightObject.transform.rotation = Quaternion.Euler(50f, -30f, 0f); } private static void CreateSystems(Dictionary items, List recipes, Dictionary materials, Font uiFont, GameObject recipeButtonPrefab, GameObject slotPrefab, GameObject hotbarSlotPrefab) { GameObject player = CreatePlayer(materials["Mat_Player"]); Camera mainCamera = Camera.main; if (mainCamera != null) { CameraFollow follow = mainCamera.gameObject.AddComponent(); follow.target = player.transform; } GameObject inventoryObject = new GameObject("Player Inventory"); Inventory inventory = inventoryObject.AddComponent(); inventory.maxSlots = 32; inventory.testResources = new List { new InventorySlot(items["Wood"], 8), new InventorySlot(items["Stone"], 6), new InventorySlot(items["Stick"], 6), new InventorySlot(items["IronOre"], 4), new InventorySlot(items["Fiber"], 6), new InventorySlot(items["Leather"], 2), new InventorySlot(items["Coal"], 3), new InventorySlot(items["Herb"], 3), new InventorySlot(items["Crystal"], 2) }; GameObject craftingObject = new GameObject("Crafting System"); CraftingSystem craftingSystem = craftingObject.AddComponent(); craftingSystem.playerInventory = inventory; craftingSystem.availableRecipes = recipes; craftingSystem.lastMessage = "Собирайте ресурсы на карте, затем создавайте предметы справа."; GameObject canvasObject = new GameObject("Canvas"); Canvas canvas = canvasObject.AddComponent(); canvas.renderMode = RenderMode.ScreenSpaceOverlay; CanvasScaler scaler = canvasObject.AddComponent(); scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; scaler.referenceResolution = new Vector2(1280f, 720f); scaler.matchWidthOrHeight = 0.5f; canvasObject.AddComponent(); GameObject eventSystemObject = new GameObject("EventSystem"); eventSystemObject.AddComponent(); eventSystemObject.AddComponent(); RectTransform root = canvasObject.GetComponent(); Text title = CreateText("Title", root, "Лабораторная работа №3 - Система крафта", uiFont, 22, FontStyle.Bold, TextAnchor.MiddleCenter, Color.white); Anchor(title.rectTransform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -22f), new Vector2(720f, 36f)); Image inventoryPanel = CreatePanel("Inventory Panel", root, new Vector2(150f, -246f), new Vector2(272f, 374f), new Vector2(0f, 1f), new Color(0.055f, 0.070f, 0.085f, 0.97f)); Image recipePanel = CreatePanel("Recipe Panel", root, new Vector2(-196f, -246f), new Vector2(364f, 374f), new Vector2(1f, 1f), new Color(0.055f, 0.070f, 0.085f, 0.97f)); Image detailsPanel = CreatePanel("Recipe Details Panel", root, new Vector2(0f, 158f), new Vector2(500f, 116f), new Vector2(0.5f, 0f), new Color(0.055f, 0.070f, 0.085f, 0.96f)); Image hotbarPanel = CreatePanel("Hotbar Panel", root, new Vector2(0f, 42f), new Vector2(878f, 68f), new Vector2(0.5f, 0f), new Color(0.045f, 0.055f, 0.070f, 0.97f)); Text inventoryTitle = CreateText("Inventory Title", inventoryPanel.rectTransform, "Инвентарь", uiFont, 20, FontStyle.Bold, TextAnchor.MiddleLeft, Color.white); Anchor(inventoryTitle.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 160f), new Vector2(240f, 30f)); Transform slotContainer = CreateVerticalContainer("Inventory Slots", inventoryPanel.rectTransform, new Vector2(0f, 4f), new Vector2(248f, 270f), new Vector2(0.5f, 0.5f), 4f, TextAnchor.UpperCenter); Text inventoryDebug = CreateText("Inventory Debug", inventoryPanel.rectTransform, "Ресурсов: 9", uiFont, 14, FontStyle.Normal, TextAnchor.LowerLeft, new Color(0.78f, 0.84f, 0.88f)); Anchor(inventoryDebug.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -162f), new Vector2(240f, 24f)); Text recipeTitle = CreateText("Recipe Title", recipePanel.rectTransform, "Рецепты", uiFont, 20, FontStyle.Bold, TextAnchor.MiddleLeft, Color.white); Anchor(recipeTitle.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 160f), new Vector2(336f, 30f)); Transform recipeContainer = CreateRectContainer("Recipe Buttons", recipePanel.rectTransform, new Vector2(0f, -8f), new Vector2(336f, 286f), new Vector2(0.5f, 0.5f)); Text recipeDebug = CreateText("Recipe Debug", recipePanel.rectTransform, "Рецептов: 5", uiFont, 14, FontStyle.Normal, TextAnchor.LowerLeft, new Color(0.78f, 0.84f, 0.88f)); Anchor(recipeDebug.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -162f), new Vector2(336f, 24f)); Text selectedRecipeText = CreateText("Selected Recipe Text", detailsPanel.rectTransform, "", uiFont, 12, FontStyle.Normal, TextAnchor.UpperLeft, new Color(0.88f, 0.92f, 0.95f)); Stretch(selectedRecipeText.rectTransform, 12f, 8f, 12f, 34f); Text messageText = CreateText("Craft Message", detailsPanel.rectTransform, "Собирайте ресурсы на карте, затем создавайте предметы справа.", uiFont, 13, FontStyle.Bold, TextAnchor.MiddleLeft, new Color(0.74f, 0.95f, 0.70f)); Anchor(messageText.rectTransform, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(12f, 18f), new Vector2(-24f, 28f)); Text interactionText = CreateText("Interaction Text", root, "Подойдите к ресурсу и нажмите E", uiFont, 16, FontStyle.Bold, TextAnchor.MiddleCenter, new Color(1f, 0.92f, 0.62f)); Anchor(interactionText.rectTransform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -56f), new Vector2(540f, 28f)); Text hintText = CreateText("Hint Text", root, "WASD - движение | E - подобрать | 1-9/0 - слот | F - использовать | R - тестовые ресурсы | C - UI", uiFont, 13, FontStyle.Normal, TextAnchor.MiddleCenter, new Color(0.84f, 0.89f, 0.92f)); Anchor(hintText.rectTransform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -84f), new Vector2(850f, 24f)); Transform hotbarContainer = CreateHorizontalContainer("Hotbar Slots", hotbarPanel.rectTransform, new Vector2(0f, 0f), new Vector2(854f, 54f), new Vector2(0.5f, 0.5f), 6f, TextAnchor.MiddleCenter); InventoryUI inventoryUI = inventoryPanel.gameObject.AddComponent(); inventoryUI.inventory = inventory; inventoryUI.slotContainer = slotContainer; inventoryUI.slotPrefab = slotPrefab; CraftingUI craftingUI = recipePanel.gameObject.AddComponent(); craftingUI.craftingSystem = craftingSystem; craftingUI.inventory = inventory; craftingUI.recipeContainer = recipeContainer; craftingUI.recipeButtonPrefab = recipeButtonPrefab; craftingUI.messageText = messageText; craftingUI.selectedRecipeText = selectedRecipeText; craftingUI.uiFont = uiFont; PlayerMovement movement = player.GetComponent(); PlayerInteractor interactor = player.AddComponent(); interactor.inventory = inventory; interactor.craftingSystem = craftingSystem; interactor.interactionText = interactionText; ItemUseSystem itemUseSystem = player.AddComponent(); itemUseSystem.inventory = inventory; itemUseSystem.craftingSystem = craftingSystem; itemUseSystem.playerMovement = movement; itemUseSystem.playerTransform = player.transform; itemUseSystem.torchLightMaterial = materials["Mat_Torch_Light"]; itemUseSystem.statusText = messageText; itemUseSystem.selectableSlotCount = 10; HotbarUI hotbarUI = hotbarPanel.gameObject.AddComponent(); hotbarUI.inventory = inventory; hotbarUI.itemUseSystem = itemUseSystem; hotbarUI.slotContainer = hotbarContainer; hotbarUI.slotPrefab = hotbarSlotPrefab; hotbarUI.slotCount = 10; GameObject controllerObject = new GameObject("Crafting Demo Controller"); CraftingDemoController controller = controllerObject.AddComponent(); controller.inventory = inventory; controller.craftingSystem = craftingSystem; controller.craftingPanel = canvasObject; controller.hintText = hintText; controller.addStartingResources = false; ApplyFontToAllText(canvasObject, uiFont); } private static GameObject CreateRecipeButtonPrefab(Font font) { GameObject root = new GameObject("RecipeButtonPrefab", typeof(RectTransform), typeof(Image), typeof(Button)); RectTransform rect = root.GetComponent(); rect.sizeDelta = new Vector2(336f, 52f); Image image = root.GetComponent(); image.color = new Color(0.13f, 0.18f, 0.20f, 0.98f); Button button = root.GetComponent