60 lines
2.4 KiB
C#
60 lines
2.4 KiB
C#
using UnityEngine;
|
|
namespace FlappyBird.Gameplay.Pipes
|
|
{
|
|
/// <summary>
|
|
/// Pure C# service — all pipe-spawning and timing logic.
|
|
/// No MonoBehaviour, no Unity lifecycle. Ticked externally by PipeSpawnerTicker.
|
|
/// </summary>
|
|
public sealed class PipeSpawner : IPipeSpawner
|
|
{
|
|
private readonly IPipePool _pool;
|
|
private readonly PipeSettings _settings;
|
|
private float _timer;
|
|
/// <summary>Constructor injection.</summary>
|
|
public PipeSpawner(IPipePool pool, PipeSettings settings)
|
|
{
|
|
_pool = pool;
|
|
_settings = settings;
|
|
}
|
|
// ── IPipeSpawner ───────────────────────────────────────────────────
|
|
/// <inheritdoc/>
|
|
public void Tick(float deltaTime)
|
|
{
|
|
_timer += deltaTime;
|
|
if (_timer >= _settings.SpawnInterval)
|
|
{
|
|
_timer -= _settings.SpawnInterval;
|
|
SpawnPair();
|
|
}
|
|
}
|
|
/// <inheritdoc/>
|
|
public void ResetTimer() => _timer = 0f;
|
|
// ── Private helpers ────────────────────────────────────────────────
|
|
/// <summary>
|
|
/// Fetches a pipe pair from the pool, positions it with a random gap centre,
|
|
/// then places the top and bottom pipe transforms around that gap.
|
|
/// </summary>
|
|
private void SpawnPair()
|
|
{
|
|
float gapCentreY = Random.Range(_settings.MinGapCentreY, _settings.MaxGapCentreY);
|
|
float halfGap = _settings.GapSize * 0.5f;
|
|
float pipeOffset = _settings.PipeHalfHeight; // shifts pivot to tip when centred
|
|
|
|
PipeView pipe = _pool.Get();
|
|
|
|
pipe.transform.position = new Vector3(_settings.SpawnX, 0f, 0f);
|
|
|
|
// Bottom pipe: pivot centre pushed downward so the tip meets the gap edge.
|
|
pipe.BottomPipe.position = new Vector3(
|
|
_settings.SpawnX,
|
|
gapCentreY - halfGap - pipeOffset,
|
|
0f);
|
|
|
|
// Top pipe: pivot centre pushed upward so the tip meets the gap edge.
|
|
pipe.TopPipe.position = new Vector3(
|
|
_settings.SpawnX,
|
|
gapCentreY + halfGap + pipeOffset,
|
|
0f);
|
|
}
|
|
}
|
|
} |