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'ы и добавлены сопутствующие проектные артефакты, которые сейчас используются обновлённой конфигурацией проекта
179 lines
5.3 KiB
C#
179 lines
5.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Collections;
|
|
using RR.Common.Settings;
|
|
using UnityEngine;
|
|
|
|
namespace RR.Game2D.Behaviour
|
|
{
|
|
[DisallowMultipleComponent]
|
|
public sealed class EntitySpawnerManager : MonoBehaviour
|
|
{
|
|
[Header("Spawners")]
|
|
[SerializeField] private EntitySpawner[] spawners;
|
|
[SerializeField] private bool includeChildren = true;
|
|
[SerializeField] private bool includeInactiveChildren = true;
|
|
|
|
[Header("Initialize Spawn")]
|
|
[SerializeField] private bool spawnOnInitialize;
|
|
[Tooltip("Если включено, процент спавна берётся из настройки gameplay.gameDifficulty.")]
|
|
[SerializeField] private bool useSettings = true;
|
|
[Range(0f, 100f)]
|
|
[SerializeField] private float initializeSpawnPercent = 100f;
|
|
|
|
private readonly List<EntitySpawner> _resolvedSpawners = new();
|
|
private readonly HashSet<EntitySpawner> _deduplicationSet = new();
|
|
private const string GameDifficultyKey = "gameplay.gameDifficulty";
|
|
private const float SettingsWaitTimeout = 2f;
|
|
|
|
public int LastSpawnedCount { get; private set; }
|
|
|
|
private void Start()
|
|
{
|
|
if (!spawnOnInitialize)
|
|
return;
|
|
|
|
StartCoroutine(InitializeSpawnRoutine());
|
|
}
|
|
|
|
public void SpawnConfiguredPercent()
|
|
{
|
|
SpawnPercent(GetConfiguredSpawnPercent());
|
|
}
|
|
|
|
public void SpawnPercent(int percent)
|
|
{
|
|
SpawnPercent((float)percent);
|
|
}
|
|
|
|
public void SpawnPercent(float percent)
|
|
{
|
|
LastSpawnedCount = SpawnInternal(percent);
|
|
}
|
|
|
|
public void StartAllSpawners()
|
|
{
|
|
ResolveSpawners();
|
|
|
|
for (int i = 0; i < _resolvedSpawners.Count; i++)
|
|
{
|
|
if (_resolvedSpawners[i] != null)
|
|
_resolvedSpawners[i].StartSpawning();
|
|
}
|
|
}
|
|
|
|
public void StopAllSpawners()
|
|
{
|
|
ResolveSpawners();
|
|
|
|
for (int i = 0; i < _resolvedSpawners.Count; i++)
|
|
{
|
|
if (_resolvedSpawners[i] != null)
|
|
_resolvedSpawners[i].StopSpawning();
|
|
}
|
|
}
|
|
|
|
public void ClearAllSpawned()
|
|
{
|
|
ResolveSpawners();
|
|
|
|
for (int i = 0; i < _resolvedSpawners.Count; i++)
|
|
{
|
|
if (_resolvedSpawners[i] != null)
|
|
_resolvedSpawners[i].ClearSpawned();
|
|
}
|
|
}
|
|
|
|
private int SpawnInternal(float percent)
|
|
{
|
|
ResolveSpawners();
|
|
|
|
int totalSpawned = 0;
|
|
for (int i = 0; i < _resolvedSpawners.Count; i++)
|
|
{
|
|
EntitySpawner spawner = _resolvedSpawners[i];
|
|
if (spawner == null)
|
|
continue;
|
|
|
|
totalSpawned += spawner.SpawnPercent(percent);
|
|
}
|
|
|
|
return totalSpawned;
|
|
}
|
|
|
|
private void ResolveSpawners()
|
|
{
|
|
_resolvedSpawners.Clear();
|
|
_deduplicationSet.Clear();
|
|
|
|
if (spawners != null)
|
|
{
|
|
for (int i = 0; i < spawners.Length; i++)
|
|
TryAddSpawner(spawners[i]);
|
|
}
|
|
|
|
if (!includeChildren)
|
|
return;
|
|
|
|
EntitySpawner[] childSpawners = GetComponentsInChildren<EntitySpawner>(includeInactiveChildren);
|
|
for (int i = 0; i < childSpawners.Length; i++)
|
|
TryAddSpawner(childSpawners[i]);
|
|
}
|
|
|
|
private void TryAddSpawner(EntitySpawner spawner)
|
|
{
|
|
if (spawner == null || !_deduplicationSet.Add(spawner))
|
|
return;
|
|
|
|
_resolvedSpawners.Add(spawner);
|
|
}
|
|
|
|
private IEnumerator InitializeSpawnRoutine()
|
|
{
|
|
if (useSettings)
|
|
{
|
|
float elapsed = 0f;
|
|
while (SettingsManager.Instance == null && elapsed < SettingsWaitTimeout)
|
|
{
|
|
elapsed += Time.unscaledDeltaTime;
|
|
yield return null;
|
|
}
|
|
}
|
|
|
|
float percent = GetConfiguredSpawnPercent();
|
|
Debug.Log($"[{nameof(EntitySpawnerManager)}] Initialize spawn percent = {percent}", this);
|
|
SpawnPercent(percent);
|
|
}
|
|
|
|
private float GetConfiguredSpawnPercent()
|
|
{
|
|
if (!useSettings)
|
|
return initializeSpawnPercent;
|
|
|
|
SettingsManager settingsManager = SettingsManager.Instance;
|
|
if (settingsManager == null)
|
|
{
|
|
Debug.LogWarning(
|
|
$"[{nameof(EntitySpawnerManager)}] SettingsManager.Instance not found. Using max difficulty spawn percent.",
|
|
this);
|
|
return 100f;
|
|
}
|
|
|
|
int difficultyIndex = settingsManager.GetInt(GameDifficultyKey);
|
|
float percent = difficultyIndex switch
|
|
{
|
|
0 => 25f,
|
|
1 => 50f,
|
|
2 => 75f,
|
|
3 => 100f,
|
|
_ => 100f
|
|
};
|
|
|
|
Debug.Log(
|
|
$"[{nameof(EntitySpawnerManager)}] Difficulty index '{difficultyIndex}' from '{GameDifficultyKey}' resolved to {percent}%.",
|
|
this);
|
|
|
|
return percent;
|
|
}
|
|
}
|
|
}
|