Files
AppleHillsProduction/Assets/Scripts/Minigames/BirdPooper/TargetSpawner.cs
2025-11-21 11:33:49 +01:00

199 lines
6.7 KiB
C#

using UnityEngine;
using Core;
using Core.Settings;
using Core.Lifecycle;
using AppleHillsCamera;
namespace Minigames.BirdPooper
{
/// <summary>
/// Spawns targets at regular intervals for Bird Pooper minigame.
/// Uses Transform references for spawn and despawn positions.
/// All targets are spawned at Y = 0 (EdgeAnchor positions them vertically).
/// </summary>
public class TargetSpawner : ManagedBehaviour
{
[Header("Spawn Configuration")]
[Tooltip("Transform marking where targets spawn (off-screen right)")]
[SerializeField] private Transform spawnPoint;
[Tooltip("Transform marking where targets despawn (off-screen left)")]
[SerializeField] private Transform despawnPoint;
[Header("EdgeAnchor References")]
[Tooltip("ScreenReferenceMarker to pass to spawned targets")]
[SerializeField] private ScreenReferenceMarker referenceMarker;
[Tooltip("CameraScreenAdapter to pass to spawned targets")]
[SerializeField] private CameraScreenAdapter cameraAdapter;
[Header("Target Prefabs")]
[Tooltip("Array of target prefabs to spawn randomly")]
[SerializeField] private GameObject[] targetPrefabs;
private IBirdPooperSettings settings;
private float spawnTimer;
private bool isSpawning;
internal override void OnManagedAwake()
{
base.OnManagedAwake();
// Load settings
settings = GameManager.GetSettingsObject<IBirdPooperSettings>();
if (settings == null)
{
Debug.LogError("[TargetSpawner] BirdPooperSettings not found!");
return;
}
// Validate references
if (spawnPoint == null)
{
Debug.LogError("[TargetSpawner] Spawn Point not assigned! Please assign a Transform in the Inspector.");
}
if (despawnPoint == null)
{
Debug.LogError("[TargetSpawner] Despawn Point not assigned! Please assign a Transform in the Inspector.");
}
if (targetPrefabs == null || targetPrefabs.Length == 0)
{
Debug.LogError("[TargetSpawner] No target prefabs assigned! Please assign at least one prefab in the Inspector.");
}
if (referenceMarker == null)
{
Debug.LogError("[TargetSpawner] ScreenReferenceMarker not assigned! Targets need this for EdgeAnchor positioning.");
}
if (cameraAdapter == null)
{
Debug.LogWarning("[TargetSpawner] CameraScreenAdapter not assigned. EdgeAnchor will attempt to auto-find camera.");
}
Debug.Log("[TargetSpawner] Initialized successfully");
}
private void Update()
{
if (!isSpawning || settings == null)
return;
spawnTimer += Time.deltaTime;
if (spawnTimer >= settings.TargetSpawnInterval)
{
SpawnTarget();
spawnTimer = 0f;
}
}
/// <summary>
/// Spawns a random target prefab at the spawn point.
/// Target is spawned at Y = 0, EdgeAnchor will position it vertically.
/// </summary>
private void SpawnTarget()
{
if (targetPrefabs == null || targetPrefabs.Length == 0 || spawnPoint == null)
{
Debug.LogError("[TargetSpawner] Cannot spawn target - missing prefabs or spawn point!");
return;
}
// Randomly select target prefab
GameObject prefab = targetPrefabs[Random.Range(0, targetPrefabs.Length)];
// Spawn at spawn point X, but Y = 0 (EdgeAnchor will position vertically)
Vector3 spawnPosition = new Vector3(spawnPoint.position.x, 0f, 0f);
GameObject targetObj = Instantiate(prefab, spawnPosition, Quaternion.identity);
// Initialize target
Target target = targetObj.GetComponent<Target>();
if (target != null)
{
float despawnX = despawnPoint != null ? despawnPoint.position.x : -12f;
target.Initialize(despawnX, referenceMarker, cameraAdapter);
// Subscribe to target hit event to notify manager
target.onTargetHit.AddListener(OnTargetHit);
Debug.Log($"[TargetSpawner] Spawned target at {spawnPosition}");
}
else
{
Debug.LogError($"[TargetSpawner] Spawned prefab '{prefab.name}' does not have Target component!");
Destroy(targetObj);
}
}
/// <summary>
/// Called when a target is hit by a projectile.
/// Notifies the game manager for score tracking.
/// </summary>
private void OnTargetHit()
{
// Find and notify manager
BirdPooperGameManager manager = BirdPooperGameManager.Instance;
if (manager != null)
{
manager.OnTargetHit();
}
else
{
Debug.LogWarning("[TargetSpawner] BirdPooperGameManager not found!");
}
}
/// <summary>
/// Start spawning targets at regular intervals.
/// </summary>
public void StartSpawning()
{
isSpawning = true;
spawnTimer = 0f;
Debug.Log("[TargetSpawner] Started spawning targets");
}
/// <summary>
/// Stop spawning new targets (existing targets continue).
/// </summary>
public void StopSpawning()
{
isSpawning = false;
Debug.Log("[TargetSpawner] Stopped spawning targets");
}
/// <summary>
/// Check if spawner is currently spawning.
/// </summary>
public bool IsSpawning => isSpawning;
/// <summary>
/// Draw gizmos to visualize spawn and despawn points in the editor.
/// </summary>
private void OnDrawGizmos()
{
if (spawnPoint != null)
{
Gizmos.color = Color.cyan;
Gizmos.DrawLine(
new Vector3(spawnPoint.position.x, -10f, 0f),
new Vector3(spawnPoint.position.x, 10f, 0f)
);
}
if (despawnPoint != null)
{
Gizmos.color = Color.magenta;
Gizmos.DrawLine(
new Vector3(despawnPoint.position.x, -10f, 0f),
new Vector3(despawnPoint.position.x, 10f, 0f)
);
}
}
}
}