116 lines
3.7 KiB
C#
116 lines
3.7 KiB
C#
|
|
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);
|
|||
|
|
}
|
|||
|
|
*/
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|