124 lines
4.1 KiB
C#
124 lines
4.1 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Minigames.Airplane.Interactive
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// Bounces airplanes on collision with configurable bounce multiplier.
|
|||
|
|
/// Can be used for trampolines, bounce pads, or elastic surfaces.
|
|||
|
|
/// </summary>
|
|||
|
|
[RequireComponent(typeof(Collider2D))]
|
|||
|
|
public class AirplaneBouncySurface : MonoBehaviour
|
|||
|
|
{
|
|||
|
|
[Header("Bounce Configuration")]
|
|||
|
|
[SerializeField] private float bounceMultiplier = 1.5f;
|
|||
|
|
[SerializeField] private Vector2 bounceDirection = Vector2.up;
|
|||
|
|
[SerializeField] private bool useReflection = true;
|
|||
|
|
|
|||
|
|
[Header("Optional Modifiers")]
|
|||
|
|
[SerializeField] private float minBounceVelocity = 2f;
|
|||
|
|
[SerializeField] private float maxBounceVelocity = 20f;
|
|||
|
|
|
|||
|
|
[Header("Visual Feedback (Optional)")]
|
|||
|
|
[SerializeField] private Animator bounceAnimator;
|
|||
|
|
[SerializeField] private string bounceTrigger = "Bounce";
|
|||
|
|
[SerializeField] private AudioSource bounceSound;
|
|||
|
|
|
|||
|
|
[Header("Debug")]
|
|||
|
|
[SerializeField] private bool showDebugLogs;
|
|||
|
|
|
|||
|
|
private void Awake()
|
|||
|
|
{
|
|||
|
|
// Ensure collider is trigger
|
|||
|
|
var collider = GetComponent<Collider2D>();
|
|||
|
|
if (collider != null)
|
|||
|
|
{
|
|||
|
|
collider.isTrigger = true;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnTriggerEnter2D(Collider2D other)
|
|||
|
|
{
|
|||
|
|
// Check if it's an airplane
|
|||
|
|
var airplane = other.GetComponent<Core.AirplaneController>();
|
|||
|
|
if (airplane == null || !airplane.IsFlying) return;
|
|||
|
|
|
|||
|
|
var rb = other.GetComponent<Rigidbody2D>();
|
|||
|
|
if (rb == null) return;
|
|||
|
|
|
|||
|
|
// Calculate bounce velocity
|
|||
|
|
Vector2 newVelocity;
|
|||
|
|
|
|||
|
|
if (useReflection)
|
|||
|
|
{
|
|||
|
|
// Reflect velocity around bounce direction (normal)
|
|||
|
|
Vector2 normal = bounceDirection.normalized;
|
|||
|
|
newVelocity = Vector2.Reflect(rb.linearVelocity, normal) * bounceMultiplier;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// Direct bounce in specified direction
|
|||
|
|
float speed = rb.linearVelocity.magnitude * bounceMultiplier;
|
|||
|
|
newVelocity = bounceDirection.normalized * speed;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Clamp velocity
|
|||
|
|
float magnitude = newVelocity.magnitude;
|
|||
|
|
if (magnitude < minBounceVelocity)
|
|||
|
|
{
|
|||
|
|
newVelocity = newVelocity.normalized * minBounceVelocity;
|
|||
|
|
}
|
|||
|
|
else if (magnitude > maxBounceVelocity)
|
|||
|
|
{
|
|||
|
|
newVelocity = newVelocity.normalized * maxBounceVelocity;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Apply bounce
|
|||
|
|
rb.linearVelocity = newVelocity;
|
|||
|
|
|
|||
|
|
// Visual/audio feedback
|
|||
|
|
PlayBounceEffects();
|
|||
|
|
|
|||
|
|
if (showDebugLogs)
|
|||
|
|
{
|
|||
|
|
Debug.Log($"[AirplaneBouncySurface] Bounced {other.name}: velocity={newVelocity}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void PlayBounceEffects()
|
|||
|
|
{
|
|||
|
|
// Trigger animation
|
|||
|
|
if (bounceAnimator != null && !string.IsNullOrEmpty(bounceTrigger))
|
|||
|
|
{
|
|||
|
|
bounceAnimator.SetTrigger(bounceTrigger);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Play sound
|
|||
|
|
if (bounceSound != null)
|
|||
|
|
{
|
|||
|
|
bounceSound.Play();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnDrawGizmos()
|
|||
|
|
{
|
|||
|
|
// Visualize bounce direction in editor
|
|||
|
|
Gizmos.color = Color.cyan;
|
|||
|
|
|
|||
|
|
var collider = GetComponent<Collider2D>();
|
|||
|
|
if (collider != null)
|
|||
|
|
{
|
|||
|
|
Vector3 center = collider.bounds.center;
|
|||
|
|
Vector3 direction = bounceDirection.normalized;
|
|||
|
|
|
|||
|
|
// Draw arrow showing bounce direction
|
|||
|
|
Gizmos.DrawRay(center, direction * 2f);
|
|||
|
|
Gizmos.DrawWireSphere(center + direction * 2f, 0.3f);
|
|||
|
|
|
|||
|
|
// Draw surface bounds
|
|||
|
|
Gizmos.DrawWireCube(collider.bounds.center, collider.bounds.size);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|