2025-09-21 07:32:56 +00:00
using UnityEngine ;
using System.Collections ;
2025-09-24 13:33:43 +00:00
using AppleHills.Core.Settings ;
2025-10-14 15:53:58 +02:00
using Core ;
2025-09-21 07:32:56 +00:00
namespace Minigames.DivingForPictures
{
/// <summary>
/// Collision behavior that bumps the player toward the center of the trench.
/// Uses trigger-based collision detection with coroutine-based bump timing.
/// </summary>
public class TileBumpCollision : PlayerCollisionBehavior
{
private bool _isBumping ;
private Coroutine _bumpCoroutine ;
2025-09-24 13:33:43 +00:00
2025-09-21 07:32:56 +00:00
protected override void HandleCollisionResponse ( Collider2D obstacle )
{
2025-09-24 13:33:43 +00:00
// Check if the obstacle is on the TrenchTileLayer
if ( obstacle . gameObject . layer ! = _devSettings . TrenchTileLayer )
{
// If not on the trench tile layer, don't process the collision
2025-10-14 15:53:58 +02:00
Logging . Debug ( $"[TileBumpCollision] Ignored collision with object on layer {obstacle.gameObject.layer} (expected {_devSettings.TrenchTileLayer})" ) ;
2025-09-24 13:33:43 +00:00
return ;
}
// Use bump mode from developer settings
switch ( _devSettings . BumpMode )
2025-09-21 07:32:56 +00:00
{
case BumpMode . Impulse :
StartImpulseBump ( ) ;
break ;
case BumpMode . SmoothToCenter :
StartSmoothMoveToCenter ( ) ;
break ;
}
2025-10-14 15:53:58 +02:00
Logging . Debug ( $"[TileBumpCollision] Collision handled with {_devSettings.BumpMode} mode" ) ;
2025-09-21 07:32:56 +00:00
}
/// <summary>
/// Starts an impulse bump toward the center with force-based distance
/// </summary>
private void StartImpulseBump ( )
{
if ( playerCharacter = = null ) return ;
float currentX = playerCharacter . transform . position . x ;
// Calculate bump distance based on force and current position
float directionToCenter = currentX > 0 ? - 1f : 1f ; // Direction toward center
// Calculate target position - closer to center based on bump force
2025-09-24 13:33:43 +00:00
float bumpDistance = _gameSettings . BumpForce * 0.2f ; // Scale factor for distance
2025-09-21 07:32:56 +00:00
float targetX = currentX + ( directionToCenter * bumpDistance ) ;
// Clamp to center if we would overshoot
if ( ( currentX > 0 & & targetX < 0 ) | | ( currentX < 0 & & targetX > 0 ) )
{
targetX = 0f ;
}
float bumpDuration = 0.5f ; // Fixed duration for impulse
StartBump ( currentX , targetX , bumpDuration ) ;
2025-10-14 15:53:58 +02:00
Logging . Debug ( $"[TileBumpCollision] Starting impulse bump from X={currentX} to X={targetX} (force={_gameSettings.BumpForce})" ) ;
2025-09-21 07:32:56 +00:00
}
/// <summary>
/// Starts smooth movement to the center
/// </summary>
private void StartSmoothMoveToCenter ( )
{
if ( playerCharacter = = null ) return ;
float currentX = playerCharacter . transform . position . x ;
float distanceToCenter = Mathf . Abs ( currentX ) ;
float targetX = 0f ; // Always move to center
2025-09-24 13:33:43 +00:00
float bumpDuration = distanceToCenter / _gameSettings . SmoothMoveSpeed ; // Duration based on distance and speed
2025-09-21 07:32:56 +00:00
StartBump ( currentX , targetX , bumpDuration ) ;
2025-10-14 15:53:58 +02:00
Logging . Debug ( $"[TileBumpCollision] Starting smooth move to center from X={currentX} (speed={_gameSettings.SmoothMoveSpeed}, duration={bumpDuration:F2}s)" ) ;
2025-09-21 07:32:56 +00:00
}
/// <summary>
/// Common bump initialization using coroutines
/// </summary>
private void StartBump ( float startX , float targetX , float duration )
{
// Stop any existing bump
if ( _bumpCoroutine ! = null )
{
StopCoroutine ( _bumpCoroutine ) ;
_bumpCoroutine = null ;
}
_isBumping = true ;
// Start bump coroutine
_bumpCoroutine = StartCoroutine ( BumpCoroutine ( startX , targetX , duration ) ) ;
}
/// <summary>
/// Coroutine that handles the bump movement over time
/// </summary>
private IEnumerator BumpCoroutine ( float startX , float targetX , float duration )
{
float elapsedTime = 0f ;
while ( elapsedTime < duration )
{
elapsedTime + = Time . deltaTime ;
// Calculate progress and apply curve
float progress = elapsedTime / duration ;
2025-09-24 13:33:43 +00:00
float curveValue = _devSettings . BumpCurve . Evaluate ( progress ) ;
2025-09-21 07:32:56 +00:00
// Interpolate position
float currentX = Mathf . Lerp ( startX , targetX , curveValue ) ;
// Apply the position to the player character
if ( playerCharacter ! = null )
{
Vector3 currentPos = playerCharacter . transform . position ;
2025-09-24 13:33:43 +00:00
currentPos . x = Mathf . Clamp ( currentX , _gameSettings . ClampXMin , _gameSettings . ClampXMax ) ;
playerCharacter . transform . position = currentPos ;
2025-09-21 07:32:56 +00:00
}
yield return null ;
}
// Ensure we end exactly at target
if ( playerCharacter ! = null )
{
Vector3 currentPos = playerCharacter . transform . position ;
2025-09-24 13:33:43 +00:00
float clampedTargetX = Mathf . Clamp ( targetX , _gameSettings . ClampXMin , _gameSettings . ClampXMax ) ;
playerCharacter . transform . position = new Vector3 ( clampedTargetX , currentPos . y , currentPos . z ) ;
2025-09-21 07:32:56 +00:00
}
// Bump finished
_isBumping = false ;
_bumpCoroutine = null ;
2025-10-14 15:53:58 +02:00
Logging . Debug ( "[TileBumpCollision] Bump movement completed" ) ;
2025-09-21 07:32:56 +00:00
}
}
}