Some checks failed
Gitea Actions Demo / Explore-Gitea-Actions (push) Has been cancelled
- Добавлен `ScoreSystem` — singleton-компонент, отслеживающий монеты, убитых врагов и экологические очки; финальный счёт вычисляется по формуле `Score = E × (P + 45C + 90K + 10K²) − 0.5T` с раздельными множителями для победы и проигрыша. - Добавлен `EnvironmentalCollectibleBase` — абстрактный базовый класс для подбираемых экологических объектов: срабатывает по триггеру, поддерживает пулинг, при подборе регистрирует очки в `ScoreSystem`. - Добавлен `LeafCollectible` — листик с синусоидальным горизонтальным дрейфом, вращением и детекцией земли. - Добавлен `BatCollectible` — летучая мышь с синусоидальным вертикальным движением, ограниченным горизонтальным блужданием и случайными сменами направления; переворачивает спрайт по X при смене направления. - Добавлен `EnvironmentalPool` — простой объектный пул по prefab-ключу с прогревом (`Warmup`) и возвратом объектов. - Добавлен `EnvironmentalCollectibleSpawner` — взвешенный случайный спаунер, поддерживающий фиксированное количество активных объектов; поддерживает лимиты по типу, принудительный выбор одного prefab и область спауна через `BoxCollider2D` или ручной `Bounds`. - В `CoinCollectible.TryPickup` добавлен вызов `ScoreSystem.Instance?.RegisterCoinCollected()`. - В `EnemyController.Die` добавлен guard через флаг `_isDead` для предотвращения повторного срабатывания; добавлен вызов `ScoreSystem.Instance?.RegisterEnemyKilled()`. - В `GameManager` добавлен вызов `ScoreSystem.Instance?.ResetStats()` при старте новой игры и при потере жизни.
61 lines
1.9 KiB
C#
61 lines
1.9 KiB
C#
using System.Collections.Generic;
|
|
using RR.Common.Entities.Props;
|
|
using UnityEngine;
|
|
|
|
namespace RR.Game2D.Behaviour
|
|
{
|
|
public sealed class EnvironmentalPool : MonoBehaviour
|
|
{
|
|
private readonly Dictionary<GameObject, Queue<GameObject>> _poolByPrefab = new();
|
|
|
|
public void Warmup(GameObject prefab, int count)
|
|
{
|
|
if (prefab == null || count <= 0) return;
|
|
|
|
Queue<GameObject> queue = GetQueue(prefab);
|
|
for (int i = queue.Count; i < count; i++)
|
|
{
|
|
GameObject instance = Instantiate(prefab, transform);
|
|
instance.SetActive(false);
|
|
queue.Enqueue(instance);
|
|
}
|
|
}
|
|
|
|
public GameObject Get(GameObject prefab, Vector3 position, Quaternion rotation)
|
|
{
|
|
if (prefab == null) return null;
|
|
|
|
Queue<GameObject> queue = GetQueue(prefab);
|
|
GameObject instance = queue.Count > 0 ? queue.Dequeue() : Instantiate(prefab, transform);
|
|
|
|
Transform cachedTransform = instance.transform;
|
|
cachedTransform.SetPositionAndRotation(position, rotation);
|
|
instance.SetActive(true);
|
|
|
|
return instance;
|
|
}
|
|
|
|
public void Return(GameObject prefab, GameObject instance)
|
|
{
|
|
if (prefab == null || instance == null) return;
|
|
|
|
EnvironmentalCollectibleBase collectible = instance.GetComponent<EnvironmentalCollectibleBase>();
|
|
if (collectible != null)
|
|
collectible.transform.SetParent(transform, false);
|
|
|
|
instance.SetActive(false);
|
|
GetQueue(prefab).Enqueue(instance);
|
|
}
|
|
|
|
private Queue<GameObject> GetQueue(GameObject prefab)
|
|
{
|
|
if (_poolByPrefab.TryGetValue(prefab, out Queue<GameObject> queue))
|
|
return queue;
|
|
|
|
queue = new Queue<GameObject>();
|
|
_poolByPrefab.Add(prefab, queue);
|
|
return queue;
|
|
}
|
|
}
|
|
}
|