using System; using System.Collections.Generic; using System.Linq; using Components.TileObjects; using Core; using Settings; using UnityEngine; using Application = Core.Application; using Random = UnityEngine.Random; namespace Systems { [Serializable] public class Spawn { public ObjectList objectType; public float spawnWeight; [Range(1, 5)] public int minLanes = 1; [Range(1, 5)] public int maxLanes = 5; } public class SpawnerSystem : SystemBase, ITick { [SerializeField] private Transform spawnPoint; private Spawn[] _objects; private float _speed; private float _spawnTime; private float _startTime; private int _spawnCount; private List _activeSpawns; private PoolSystem _pSystem; private PoolSystem PoolSystem { get { if (_pSystem == null) _pSystem = Application.GetSystem(); return _pSystem; } } protected override void ReleaseReferences() { _pSystem = null; spawnPoint = null; } public override void Initialize() { _activeSpawns = new List(); } public override void StartSystem() { base.StartSystem(); for (var i = 0; i < _spawnCount; i++) _activeSpawns[i].ResumeMovement(); _startTime = Time.time; } public override void StopSystem() { base.StopSystem(); for (var i = 0; i < _spawnCount; i++) _activeSpawns[i].PauseMovement(); } public void UpdateSettings(DifficultyStage inConfig) { _spawnTime = inConfig.spawnRate; _speed = inConfig.spawnSpeed; _objects = inConfig.objectsToSpawn; for (var i = 0; i < _spawnCount; i++) _activeSpawns[i].UpdateSpeed(_speed); } public void Tick() { if (!IsRun) return; if (Time.time < _startTime + _spawnTime) return; SpawnObject(); _startTime = Time.time; } private void SpawnObject() { var spawnData = GetSpawnObject(); if (spawnData == null) return; var spawnedObject = PoolSystem.Spawn(spawnData.objectType, spawnPoint); spawnedObject.Initialize((spawnData.minLanes, spawnData.maxLanes)); spawnedObject.OnReset += ResetObject; spawnedObject.MoveObject(_speed); _spawnCount++; _activeSpawns.Add(spawnedObject); return; Spawn GetSpawnObject() { if (_objects.IsNullOrEmpty()) return null; var totalWeights = 0f; foreach (var spawn in _objects) totalWeights += spawn.spawnWeight; var randomValue = Random.Range(0, totalWeights); foreach (var spawn in _objects) { randomValue -= spawn.spawnWeight; if (randomValue <= 0) return spawn; // if (randomValue < spawn.spawnWeight) // return spawn; // randomValue -= spawn.spawnWeight; } return _objects.LastOrDefault(); } } private void ResetObject(TileObject inObject) { _spawnCount--; _activeSpawns.Remove(inObject); inObject.ResetObject(); PoolSystem.Despawn(inObject.Transform); } } }