Some b ase obstacle and poop spawning

This commit is contained in:
Michal Pikulski
2025-11-21 09:22:06 +01:00
parent 8b283774e6
commit b4b17c18ed
11 changed files with 1297 additions and 22 deletions

View File

@@ -17,6 +17,11 @@ namespace Minigames.BirdPooper
[SerializeField] private BirdPlayerController player;
[SerializeField] private ObstacleSpawner obstacleSpawner;
[SerializeField] private GameOverScreen gameOverScreen;
[SerializeField] private GameObject poopPrefab;
[Header("Game State")]
private int targetsHit;
private bool isGameOver;
internal override void OnManagedAwake()
{
@@ -51,12 +56,21 @@ namespace Minigames.BirdPooper
// Hide game over screen on start
gameOverScreen.gameObject.SetActive(false);
}
if (poopPrefab == null)
{
Debug.LogWarning("[BirdPooperGameManager] Poop prefab not assigned!");
}
}
internal override void OnManagedStart()
{
base.OnManagedStart();
// Initialize game state
isGameOver = false;
targetsHit = 0;
// Subscribe to player events
if (player != null)
{
@@ -95,7 +109,10 @@ namespace Minigames.BirdPooper
/// </summary>
private void HandlePlayerDamaged()
{
Debug.Log("[BirdPooperGameManager] Player damaged - showing game over screen");
if (isGameOver) return;
isGameOver = true;
Debug.Log($"[BirdPooperGameManager] Player damaged - Game Over! Targets Hit: {targetsHit}");
// Stop spawning obstacles
if (obstacleSpawner != null)
@@ -113,6 +130,39 @@ namespace Minigames.BirdPooper
Debug.LogError("[BirdPooperGameManager] GameOverScreen reference missing!");
}
}
/// <summary>
/// Spawns a poop projectile at the player's current position.
/// Called by UI button OnClick event.
/// </summary>
public void SpawnPoop()
{
if (isGameOver || player == null || poopPrefab == null)
return;
Vector3 spawnPosition = player.transform.position;
Instantiate(poopPrefab, spawnPosition, Quaternion.identity);
Debug.Log($"[BirdPooperGameManager] Spawned poop at {spawnPosition}");
}
/// <summary>
/// Called when a target is successfully hit by poop (Phase 5).
/// </summary>
public void OnTargetHit()
{
if (isGameOver) return;
targetsHit++;
Debug.Log($"[BirdPooperGameManager] Target Hit! Total: {targetsHit}");
}
#region Public Accessors
public bool IsGameOver => isGameOver;
public int TargetsHit => targetsHit;
#endregion
}
}

View File

@@ -0,0 +1,115 @@
using Core;
using Core.Lifecycle;
using Core.Settings;
using UnityEngine;
namespace Minigames.BirdPooper
{
/// <summary>
/// Poop projectile that falls straight down with manual gravity.
/// Destroys when off-screen or hitting targets (Phase 5).
/// </summary>
[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
public class PoopProjectile : ManagedBehaviour
{
private IBirdPooperSettings settings;
private float verticalVelocity; // Current downward velocity
private const float GravityAcceleration = 20f; // Gravity acceleration (units/s²)
internal override void OnManagedAwake()
{
base.OnManagedAwake();
// Load settings
settings = GameManager.GetSettingsObject<IBirdPooperSettings>();
if (settings == null)
{
Debug.LogError("[PoopProjectile] BirdPooperSettings not found!");
Destroy(gameObject);
return;
}
// Initialize velocity with settings speed as starting velocity
verticalVelocity = settings.PoopFallSpeed;
// Verify Rigidbody2D configuration
Rigidbody2D rb = GetComponent<Rigidbody2D>();
if (rb != null)
{
rb.bodyType = RigidbodyType2D.Dynamic;
rb.gravityScale = 0f; // Manual gravity
rb.collisionDetectionMode = CollisionDetectionMode2D.Continuous;
}
// Verify collider is trigger (for target detection in Phase 5)
Collider2D col = GetComponent<Collider2D>();
if (col != null && !col.isTrigger)
{
Debug.LogWarning("[PoopProjectile] Collider should be set as Trigger for target detection!");
}
}
private void Update()
{
if (settings != null)
{
ApplyGravity();
FallDown();
CheckBounds();
}
}
/// <summary>
/// Apply gravity acceleration to velocity.
/// </summary>
private void ApplyGravity()
{
// Increase downward velocity over time (gravity acceleration)
verticalVelocity += GravityAcceleration * Time.deltaTime;
}
/// <summary>
/// Manual downward movement using current velocity.
/// </summary>
private void FallDown()
{
// Move straight down at current velocity
transform.position += Vector3.down * verticalVelocity * Time.deltaTime;
}
/// <summary>
/// Check if projectile is off-screen and should be destroyed.
/// </summary>
private void CheckBounds()
{
if (transform.position.y < settings.PoopDestroyYPosition)
{
Destroy(gameObject);
}
}
/// <summary>
/// Trigger collision detection for targets (Phase 5).
/// TODO: Uncomment when Target.cs is implemented in Phase 5
/// </summary>
private void OnTriggerEnter2D(Collider2D other)
{
// Phase 5 integration - currently commented out
/*
if (other.CompareTag("Target"))
{
// Notify target it was hit
Target target = other.GetComponent<Target>();
if (target != null)
{
target.OnHitByProjectile();
}
Destroy(gameObject);
}
*/
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f2c53b7e2a0042efa4c6679b992b6b6c
timeCreated: 1763711288