using UnityEngine; using System.Collections; using AppleHills.Core.Settings; namespace Minigames.DivingForPictures { /// /// Collision behavior that bumps the player toward the center of the trench. /// Uses trigger-based collision detection with coroutine-based bump timing. /// public class TileBumpCollision : PlayerCollisionBehavior { private bool _isBumping; private Coroutine _bumpCoroutine; private bool _bumpInputBlocked; // Tracks bump-specific input blocking protected override void HandleCollisionResponse(Collider2D obstacle) { // Use bump mode from developer settings switch (_devSettings.BumpMode) { case 0: // Impulse mode StartImpulseBump(); break; case 1: // SmoothToCenter mode StartSmoothMoveToCenter(); break; } Debug.Log($"[TileBumpCollision] Collision handled with {(_devSettings.BumpMode == 0 ? "Impulse" : "SmoothToCenter")} mode"); } /// /// Applies an impulse force toward center /// private void StartImpulseBump() { if (_isBumping || playerCharacter == null) return; _isBumping = true; // Block input during bump if configured if (_gameSettings.EndlessDescenderBlockInputDuringBump && playerController != null) { _bumpInputBlocked = true; // TODO: Implement input blocking } // Calculate direction to center (X = 0) float directionToCenter = Mathf.Sign(-playerCharacter.transform.position.x); // Start impulse bump coroutine if (_bumpCoroutine != null) StopCoroutine(_bumpCoroutine); _bumpCoroutine = StartCoroutine(ImpulseBumpCoroutine(directionToCenter)); Debug.Log($"[TileBumpCollision] Started impulse bump with force {_gameSettings.EndlessDescenderBumpForce} in direction {directionToCenter}"); } /// /// Smoothly moves the player to center /// private void StartSmoothMoveToCenter() { if (_isBumping || playerCharacter == null) return; _isBumping = true; // Block input during bump if configured if (_gameSettings.EndlessDescenderBlockInputDuringBump && playerController != null) { _bumpInputBlocked = true; // TODO: Implement input blocking } // Start smooth move coroutine if (_bumpCoroutine != null) StopCoroutine(_bumpCoroutine); _bumpCoroutine = StartCoroutine(SmoothMoveToCenterCoroutine()); Debug.Log($"[TileBumpCollision] Started smooth move to center with speed {_gameSettings.EndlessDescenderSmoothMoveSpeed}"); } /// /// Coroutine to handle impulse bump movement /// private IEnumerator ImpulseBumpCoroutine(float direction) { float elapsedTime = 0f; float bumpDuration = 0.5f; // Fixed duration for impulse Vector3 startPosition = playerCharacter.transform.position; while (elapsedTime < bumpDuration) { elapsedTime += Time.deltaTime; // Use evaluation time from curve for non-linear movement float t = elapsedTime / bumpDuration; float curveValue = _devSettings.BumpCurve.Evaluate(t); // Calculate movement distance based on force and curve float distance = _gameSettings.EndlessDescenderBumpForce * curveValue * Time.deltaTime; // Move the player toward center Vector3 newPosition = playerCharacter.transform.position; newPosition.x += direction * distance; // Clamp to valid range newPosition.x = Mathf.Clamp(newPosition.x, _gameSettings.EndlessDescenderClampXMin, _gameSettings.EndlessDescenderClampXMax); // Apply the position playerCharacter.transform.position = newPosition; yield return null; } // Finish bump _isBumping = false; _bumpInputBlocked = false; _bumpCoroutine = null; } /// /// Coroutine to handle smooth movement to center /// private IEnumerator SmoothMoveToCenterCoroutine() { Vector3 startPosition = playerCharacter.transform.position; Vector3 targetPosition = new Vector3(0f, startPosition.y, startPosition.z); // Calculate distance to center and expected duration float distanceToCenter = Mathf.Abs(startPosition.x); float expectedDuration = distanceToCenter / _gameSettings.EndlessDescenderSmoothMoveSpeed; float elapsedTime = 0f; // Move until we reach the center while (elapsedTime < expectedDuration) { elapsedTime += Time.deltaTime; // Calculate progress based on time and curve float t = elapsedTime / expectedDuration; float curveValue = _devSettings.BumpCurve.Evaluate(t); // Calculate interpolated position Vector3 newPosition = Vector3.Lerp(startPosition, targetPosition, curveValue); // Apply the position playerCharacter.transform.position = newPosition; yield return null; } // Ensure we end at exactly the center playerCharacter.transform.position = targetPosition; // Finish bump _isBumping = false; _bumpInputBlocked = false; _bumpCoroutine = null; } } }