Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- доработан flow призовой витрины и связанного UI: добавлены `PrizeStandButtonView` и `RulesPrizeListPage`, обновлены `PrizeStandController`, `PrizeStandPrize`, `PrizeStandModal`, `PrizeStandSettingsModal`, `LevelPrizeSettingsModal`, `QRCodeSettingsModal`, `BalanceDisplay`, `ButtonTextFocusColor` и связанные prefab'ы, чтобы улучшить настройку, навигацию, отображение кнопок и prize flow - расширена система настроек и сохранения значений: `OptionPicker` получил отдельный формат `ValueSelector`, обновлены `SettingsDatabase`, `SettingEntryDrawer`, `SettingUIItem`, `SettingsUIGenerator`, `ValueSelectorRow` и `MainSettingsDatabase.asset`, а сохранение option picker-значений, включая `gameplay.gameDifficulty`, исправлено и синхронизировано с остальными настройками - добавлены универсальные спавнеры сущностей: реализованы `EntitySpawner` и `EntitySpawnerManager` с поддержкой весов префабов, точек спавна, заполнения по проценту, ограничений на количество и автоспавна при инициализации - доработана логика игрового спавна и сложности: процент инициализационного спавна может зависеть от настройки `gameplay.gameDifficulty` с градациями 25/50/75/100, в одном цикле массового спавна повторно не используется та же точка, а gizmo спавнера теперь показывает только сами точки без линий - упрощена работа в редакторе Unity и добавлены editor-инструменты: в `GameManager` лицензия пропускается при запуске в `UNITY_EDITOR`, а `HierarchySelectionCounter`, `HierarchySelectionCountOverlay` и `HierarchyBulkRenamerWindow` добавляют подсчет выделения, realtime overlay в `SceneView` и массовое переименование объектов по правилам нумерации из Unity Project Settings - синхронизированы сцены, ресурсы и UI-ассеты под новый flow: обновлены `MainMenu`, `Level UI`, уровни `1-1` и `1-2`, строки настроек, кнопки, TMP/font assets, изображения UI, `prizes.json` и recovery-данные после правок интерфейса и логики - очищены и переразложены часть внешних и служебных ресурсов: удалён пакет `Lava_Flowing_Shader`, переименованы/заменены отдельные UI-prefab'ы и добавлены сопутствующие проектные артефакты, которые сейчас используются обновлённой конфигурацией проекта
159 lines
5.1 KiB
C#
159 lines
5.1 KiB
C#
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace RR.Common.UI
|
|
{
|
|
/// <summary>
|
|
/// Отображение кнопки ячейки витрины.
|
|
/// Поддерживает отдельные текстовые поля для номера ячейки и цены в очках.
|
|
/// Если префаб ещё не обновлён, недостающие поля будут созданы автоматически.
|
|
/// </summary>
|
|
[DisallowMultipleComponent]
|
|
public sealed class PrizeStandButtonView : MonoBehaviour
|
|
{
|
|
[Header("Labels")]
|
|
[SerializeField] private TMP_Text boxNumberText;
|
|
[SerializeField] private TMP_Text boxPriceText;
|
|
|
|
[Header("Formatting")]
|
|
[SerializeField] private string boxPriceFormat = "{0}";
|
|
|
|
public void Bind(int boxNumber, int requiredScore)
|
|
{
|
|
EnsureTextFields();
|
|
|
|
if (boxNumberText != null)
|
|
{
|
|
boxNumberText.text = boxNumber.ToString();
|
|
}
|
|
|
|
if (boxPriceText != null)
|
|
{
|
|
boxPriceText.text = FormatPrice(requiredScore);
|
|
}
|
|
}
|
|
|
|
private void EnsureTextFields()
|
|
{
|
|
if (boxNumberText != null && boxPriceText != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool createdMissingFields = false;
|
|
TMP_Text[] texts = GetComponentsInChildren<TMP_Text>(true);
|
|
if (boxNumberText == null && texts.Length > 0)
|
|
{
|
|
boxNumberText = texts[0];
|
|
}
|
|
|
|
if (boxPriceText == null)
|
|
{
|
|
for (int i = 0; i < texts.Length; i++)
|
|
{
|
|
if (texts[i] != null && texts[i] != boxNumberText)
|
|
{
|
|
boxPriceText = texts[i];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (boxNumberText == null)
|
|
{
|
|
boxNumberText = CreateTextField("BoxNumberText");
|
|
createdMissingFields = true;
|
|
}
|
|
|
|
if (boxPriceText == null)
|
|
{
|
|
boxPriceText = CreateTextField("BoxPriceText", boxNumberText);
|
|
createdMissingFields = true;
|
|
}
|
|
|
|
if (createdMissingFields)
|
|
{
|
|
ApplyDefaultLayout();
|
|
}
|
|
}
|
|
|
|
private TMP_Text CreateTextField(string objectName, TMP_Text template = null)
|
|
{
|
|
GameObject textObject = new(objectName, typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI));
|
|
textObject.transform.SetParent(transform, false);
|
|
textObject.layer = gameObject.layer;
|
|
|
|
TMP_Text created = textObject.GetComponent<TMP_Text>();
|
|
if (template != null)
|
|
{
|
|
created.font = template.font;
|
|
created.fontSharedMaterial = template.fontSharedMaterial;
|
|
created.fontSize = template.fontSize;
|
|
created.fontSizeMin = template.fontSizeMin;
|
|
created.fontSizeMax = template.fontSizeMax;
|
|
created.enableAutoSizing = template.enableAutoSizing;
|
|
created.color = template.color;
|
|
created.alignment = template.alignment;
|
|
created.raycastTarget = template.raycastTarget;
|
|
}
|
|
else
|
|
{
|
|
created.enableAutoSizing = true;
|
|
created.fontSizeMin = 10;
|
|
created.fontSizeMax = 36;
|
|
created.color = Color.black;
|
|
created.alignment = TextAlignmentOptions.Center;
|
|
}
|
|
|
|
return created;
|
|
}
|
|
|
|
private void ApplyDefaultLayout()
|
|
{
|
|
if (boxNumberText != null)
|
|
{
|
|
ConfigureTextRect(boxNumberText.rectTransform, new Vector2(0f, 0.48f), new Vector2(1f, 1f));
|
|
boxNumberText.alignment = TextAlignmentOptions.Center;
|
|
}
|
|
|
|
if (boxPriceText != null)
|
|
{
|
|
ConfigureTextRect(boxPriceText.rectTransform, new Vector2(0f, 0f), new Vector2(1f, 0.48f));
|
|
boxPriceText.alignment = TextAlignmentOptions.Center;
|
|
}
|
|
}
|
|
|
|
private static void ConfigureTextRect(RectTransform rectTransform, Vector2 anchorMin, Vector2 anchorMax)
|
|
{
|
|
if (rectTransform == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
rectTransform.anchorMin = anchorMin;
|
|
rectTransform.anchorMax = anchorMax;
|
|
rectTransform.offsetMin = Vector2.zero;
|
|
rectTransform.offsetMax = Vector2.zero;
|
|
rectTransform.anchoredPosition = Vector2.zero;
|
|
rectTransform.localScale = Vector3.one;
|
|
}
|
|
|
|
private string FormatPrice(int requiredScore)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(boxPriceFormat))
|
|
{
|
|
return requiredScore.ToString();
|
|
}
|
|
|
|
try
|
|
{
|
|
return string.Format(boxPriceFormat, requiredScore);
|
|
}
|
|
catch
|
|
{
|
|
return requiredScore.ToString();
|
|
}
|
|
}
|
|
}
|
|
}
|