Files
OTG_3/Assets/_Scripts/CraftingUI.cs
T

382 lines
13 KiB
C#
Raw Normal View History

2026-06-04 18:31:31 +03:00
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CraftingUI : MonoBehaviour
{
public CraftingSystem craftingSystem;
public Inventory inventory;
public Transform recipeContainer;
public GameObject recipeButtonPrefab;
public Text messageText;
public Text selectedRecipeText;
public Font uiFont;
private readonly List<GameObject> recipeButtons = new List<GameObject>();
private RecipeData selectedRecipe;
private void OnEnable()
{
if (craftingSystem != null)
{
craftingSystem.OnCraftingChanged += RefreshRecipeButtons;
}
if (inventory != null)
{
inventory.OnInventoryChanged += RefreshRecipeButtons;
}
BuildRecipeList();
}
private void OnDisable()
{
if (craftingSystem != null)
{
craftingSystem.OnCraftingChanged -= RefreshRecipeButtons;
}
if (inventory != null)
{
inventory.OnInventoryChanged -= RefreshRecipeButtons;
}
}
public void BuildRecipeList()
{
ClearRecipeButtons();
if (craftingSystem == null || recipeContainer == null || recipeButtonPrefab == null)
{
return;
}
ConfigureRecipeContainer();
for (int i = 0; i < craftingSystem.availableRecipes.Count; i++)
{
RecipeData recipe = craftingSystem.availableRecipes[i];
if (recipe == null)
{
continue;
}
GameObject buttonObject = Instantiate(recipeButtonPrefab, recipeContainer);
buttonObject.SetActive(true);
ConfigureRecipeButtonFrame(buttonObject, i);
recipeButtons.Add(buttonObject);
Button button = buttonObject.GetComponent<Button>();
if (button != null)
{
RecipeData capturedRecipe = recipe;
button.onClick.AddListener(() => OnCraftButtonClicked(capturedRecipe));
}
}
RefreshRecipeButtons();
if (selectedRecipe == null && craftingSystem.availableRecipes.Count > 0)
{
SelectRecipe(craftingSystem.availableRecipes[0]);
}
}
public void RefreshRecipeButtons()
{
if (craftingSystem == null)
{
return;
}
for (int i = 0; i < recipeButtons.Count; i++)
{
GameObject buttonObject = recipeButtons[i];
RecipeData recipe = i < craftingSystem.availableRecipes.Count ? craftingSystem.availableRecipes[i] : null;
if (buttonObject == null || recipe == null)
{
continue;
}
bool canCraft = craftingSystem.CanCraft(recipe);
Button button = buttonObject.GetComponent<Button>();
if (button != null)
{
button.interactable = canCraft;
}
Image background = buttonObject.GetComponent<Image>();
if (background != null)
{
background.color = canCraft
? new Color(0.12f, 0.24f, 0.18f, 0.98f)
: new Color(0.13f, 0.16f, 0.18f, 0.98f);
}
Image stateStripe = buttonObject.transform.Find("StateStripe")?.GetComponent<Image>();
if (stateStripe != null)
{
stateStripe.color = canCraft
? new Color(0.25f, 0.75f, 0.38f, 1f)
: new Color(0.44f, 0.48f, 0.52f, 1f);
}
Text title = buttonObject.transform.Find("Title")?.GetComponent<Text>();
if (title != null)
{
title.text = recipe.recipeName;
}
Text result = buttonObject.transform.Find("Result")?.GetComponent<Text>();
if (result != null)
{
result.text = recipe.GetResultText();
}
Text ingredients = buttonObject.transform.Find("Ingredients")?.GetComponent<Text>();
if (ingredients != null)
{
ingredients.text = recipe.GetIngredientsText();
}
Text status = buttonObject.transform.Find("Status")?.GetComponent<Text>();
if (status != null)
{
status.text = canCraft ? "ГОТОВО" : "НЕТ РЕС.";
status.color = canCraft
? new Color(0.76f, 0.96f, 0.72f)
: new Color(0.94f, 0.72f, 0.62f);
}
Text label = buttonObject.transform.Find("Label")?.GetComponent<Text>();
if (label != null)
{
label.gameObject.SetActive(false);
}
}
if (messageText != null)
{
messageText.text = craftingSystem.lastMessage;
}
if (selectedRecipe != null)
{
SelectRecipe(selectedRecipe);
}
}
public void SelectRecipe(RecipeData recipe)
{
selectedRecipe = recipe;
if (selectedRecipeText == null)
{
return;
}
if (recipe == null)
{
selectedRecipeText.text = "Рецепт не выбран";
return;
}
string missing = craftingSystem != null && !craftingSystem.CanCraft(recipe)
? "\nНе хватает: " + craftingSystem.GetMissingIngredientsText(recipe)
: "\nМожно создать сейчас.";
selectedRecipeText.text =
recipe.recipeName + ": " + recipe.description + "\n" +
"Ингредиенты: " + recipe.GetIngredientsText() + "\n" +
"Результат: " + recipe.GetResultText() + missing;
}
public void OnCraftButtonClicked(RecipeData recipe)
{
SelectRecipe(recipe);
if (craftingSystem != null)
{
craftingSystem.Craft(recipe);
}
}
public void ClearRecipeButtons()
{
recipeButtons.Clear();
if (recipeContainer == null)
{
return;
}
for (int i = recipeContainer.childCount - 1; i >= 0; i--)
{
Destroy(recipeContainer.GetChild(i).gameObject);
}
}
private void ConfigureRecipeContainer()
{
RectTransform containerRect = recipeContainer as RectTransform;
if (containerRect == null)
{
return;
}
VerticalLayoutGroup layoutGroup = recipeContainer.GetComponent<VerticalLayoutGroup>();
if (layoutGroup != null)
{
layoutGroup.enabled = false;
}
containerRect.anchorMin = new Vector2(0.5f, 0.5f);
containerRect.anchorMax = new Vector2(0.5f, 0.5f);
containerRect.pivot = new Vector2(0.5f, 0.5f);
containerRect.anchoredPosition = new Vector2(0f, -8f);
containerRect.sizeDelta = new Vector2(336f, 286f);
Image panelImage = GetComponent<Image>();
if (panelImage != null)
{
panelImage.color = new Color(0.055f, 0.070f, 0.085f, 0.97f);
}
Text title = transform.Find("Recipe Title")?.GetComponent<Text>();
if (title != null)
{
SetRect(title.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 160f), new Vector2(336f, 30f), new Vector2(0.5f, 0.5f));
}
Text debug = transform.Find("Recipe Debug")?.GetComponent<Text>();
if (debug != null)
{
SetRect(debug.rectTransform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -162f), new Vector2(336f, 24f), new Vector2(0.5f, 0.5f));
}
}
private void ConfigureRecipeButtonFrame(GameObject buttonObject, int index)
{
RectTransform rect = buttonObject.GetComponent<RectTransform>();
if (rect != null)
{
rect.anchorMin = new Vector2(0f, 1f);
rect.anchorMax = new Vector2(0f, 1f);
rect.pivot = new Vector2(0f, 1f);
rect.anchoredPosition = new Vector2(0f, -index * 58f);
rect.sizeDelta = new Vector2(336f, 52f);
rect.localScale = Vector3.one;
}
Image background = buttonObject.GetComponent<Image>();
if (background != null)
{
background.color = new Color(0.13f, 0.16f, 0.18f, 0.98f);
}
Text oldLabel = buttonObject.transform.Find("Label")?.GetComponent<Text>();
Font font = ResolveUIFont(oldLabel);
if (oldLabel != null)
{
oldLabel.gameObject.SetActive(false);
}
Image stateStripe = EnsureImageChild(buttonObject.transform, "StateStripe", new Color(0.44f, 0.48f, 0.52f, 1f));
SetRect(stateStripe.rectTransform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(3f, 0f), new Vector2(6f, 44f), new Vector2(0.5f, 0.5f));
Text title = EnsureTextChild(buttonObject.transform, "Title", font, 13, FontStyle.Bold, TextAnchor.UpperLeft, Color.white);
SetRect(title.rectTransform, new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(110f, -10f), new Vector2(190f, 20f), new Vector2(0.5f, 0.5f));
Text result = EnsureTextChild(buttonObject.transform, "Result", font, 12, FontStyle.Bold, TextAnchor.UpperRight, new Color(0.78f, 0.92f, 1f));
SetRect(result.rectTransform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-58f, -10f), new Vector2(100f, 20f), new Vector2(0.5f, 0.5f));
Text ingredients = EnsureTextChild(buttonObject.transform, "Ingredients", font, 9, FontStyle.Normal, TextAnchor.LowerLeft, new Color(0.82f, 0.86f, 0.88f));
ingredients.horizontalOverflow = HorizontalWrapMode.Wrap;
ingredients.verticalOverflow = VerticalWrapMode.Truncate;
SetRect(ingredients.rectTransform, new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(130f, 12f), new Vector2(230f, 20f), new Vector2(0.5f, 0.5f));
Text status = EnsureTextChild(buttonObject.transform, "Status", font, 10, FontStyle.Bold, TextAnchor.LowerRight, new Color(0.94f, 0.72f, 0.62f));
SetRect(status.rectTransform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-46f, 12f), new Vector2(76f, 18f), new Vector2(0.5f, 0.5f));
}
private Text EnsureTextChild(Transform parent, string childName, Font font, int fontSize, FontStyle style, TextAnchor alignment, Color color)
{
Transform existing = parent.Find(childName);
GameObject child = existing != null ? existing.gameObject : new GameObject(childName, typeof(RectTransform), typeof(Text));
child.transform.SetParent(parent, false);
Text text = child.GetComponent<Text>();
text.font = font != null ? font : ResolveUIFont(null);
text.fontSize = fontSize;
text.fontStyle = style;
text.alignment = alignment;
text.color = color;
text.raycastTarget = false;
text.horizontalOverflow = HorizontalWrapMode.Wrap;
text.verticalOverflow = VerticalWrapMode.Truncate;
child.SetActive(true);
return text;
}
private Font ResolveUIFont(Text preferredText)
{
if (uiFont != null)
{
return uiFont;
}
if (preferredText != null && preferredText.font != null)
{
uiFont = preferredText.font;
return uiFont;
}
Canvas canvas = GetComponentInParent<Canvas>();
if (canvas != null)
{
Text[] texts = canvas.GetComponentsInChildren<Text>(true);
for (int i = 0; i < texts.Length; i++)
{
if (texts[i] != null && texts[i].font != null && texts[i].font.name.ToLowerInvariant().Contains("ubuntu"))
{
uiFont = texts[i].font;
return uiFont;
}
}
for (int i = 0; i < texts.Length; i++)
{
if (texts[i] != null && texts[i].font != null)
{
uiFont = texts[i].font;
return uiFont;
}
}
}
uiFont = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf");
return uiFont;
}
private Image EnsureImageChild(Transform parent, string childName, Color color)
{
Transform existing = parent.Find(childName);
GameObject child = existing != null ? existing.gameObject : new GameObject(childName, typeof(RectTransform), typeof(Image));
child.transform.SetParent(parent, false);
Image image = child.GetComponent<Image>();
image.color = color;
image.raycastTarget = false;
child.SetActive(true);
return image;
}
private void SetRect(RectTransform rect, Vector2 anchorMin, Vector2 anchorMax, Vector2 anchoredPosition, Vector2 sizeDelta, Vector2 pivot)
{
rect.anchorMin = anchorMin;
rect.anchorMax = anchorMax;
rect.pivot = pivot;
rect.anchoredPosition = anchoredPosition;
rect.sizeDelta = sizeDelta;
rect.localScale = Vector3.one;
}
}