Working state for minigameobstacles
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Minigames.DivingForPictures
|
||||
{
|
||||
/// <summary>
|
||||
/// Collision behavior that bumps the player toward the center of the trench.
|
||||
/// Provides two modes: impulse (force-based push) or smooth movement to center.
|
||||
/// </summary>
|
||||
public class PlayerBumpCollisionBehavior : PlayerCollisionBehavior
|
||||
{
|
||||
[Header("Bump Settings")]
|
||||
[Tooltip("Type of bump response: Impulse pushes with force, SmoothToCenter moves directly to center")]
|
||||
[SerializeField] private BumpMode bumpMode = BumpMode.Impulse;
|
||||
|
||||
[Tooltip("Force strength for impulse bumps - higher values push further toward center")]
|
||||
[SerializeField] private float bumpForce = 5.0f;
|
||||
|
||||
[Tooltip("Speed for smooth movement to center (units per second)")]
|
||||
[SerializeField] private float smoothMoveSpeed = 8.0f;
|
||||
|
||||
[Tooltip("Animation curve controlling bump movement over time")]
|
||||
[SerializeField] private AnimationCurve bumpCurve = new AnimationCurve(new Keyframe(0f, 0f, 0f, 2f), new Keyframe(1f, 1f, 0f, 0f));
|
||||
|
||||
[Tooltip("Whether to block player input during bump movement")]
|
||||
[SerializeField] private bool blockInputDuringBump = true;
|
||||
|
||||
public enum BumpMode
|
||||
{
|
||||
Impulse, // Force-based push toward center (distance depends on force)
|
||||
SmoothToCenter // Smooth movement to center with configurable speed
|
||||
}
|
||||
|
||||
private bool _isBumping;
|
||||
private float _bumpTimer;
|
||||
private float _bumpStartX;
|
||||
private float _bumpTargetX;
|
||||
private float _bumpDuration;
|
||||
private bool _bumpInputBlocked; // Tracks bump-specific input blocking
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
|
||||
// Handle bump movement
|
||||
if (_isBumping)
|
||||
{
|
||||
_bumpTimer -= Time.deltaTime;
|
||||
|
||||
if (_bumpTimer <= 0f)
|
||||
{
|
||||
// Bump finished
|
||||
_isBumping = false;
|
||||
if (_bumpInputBlocked)
|
||||
{
|
||||
RestoreBumpInput();
|
||||
}
|
||||
|
||||
// Ensure we end exactly at target
|
||||
if (playerCharacter != null)
|
||||
{
|
||||
Vector3 currentPos = playerCharacter.transform.position;
|
||||
playerCharacter.transform.position = new Vector3(_bumpTargetX, currentPos.y, currentPos.z);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Apply bump movement
|
||||
float progress = 1f - (_bumpTimer / _bumpDuration);
|
||||
float curveValue = bumpCurve.Evaluate(progress);
|
||||
|
||||
float currentX = Mathf.Lerp(_bumpStartX, _bumpTargetX, curveValue);
|
||||
|
||||
// Apply the position to the player character
|
||||
if (playerCharacter != null)
|
||||
{
|
||||
Vector3 currentPos = playerCharacter.transform.position;
|
||||
playerCharacter.transform.position = new Vector3(currentX, currentPos.y, currentPos.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void HandleCollisionResponse(Collider2D obstacle)
|
||||
{
|
||||
switch (bumpMode)
|
||||
{
|
||||
case BumpMode.Impulse:
|
||||
StartImpulseBump();
|
||||
break;
|
||||
|
||||
case BumpMode.SmoothToCenter:
|
||||
StartSmoothMoveToCenter();
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Log($"[PlayerBumpCollisionBehavior] Collision handled with {bumpMode} mode");
|
||||
}
|
||||
|
||||
/// <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
|
||||
float bumpDistance = bumpForce * 0.2f; // Scale factor for distance
|
||||
float targetX = currentX + (directionToCenter * bumpDistance);
|
||||
|
||||
// Clamp to center if we would overshoot
|
||||
if ((currentX > 0 && targetX < 0) || (currentX < 0 && targetX > 0))
|
||||
{
|
||||
targetX = 0f;
|
||||
}
|
||||
|
||||
// Set bump parameters
|
||||
_bumpStartX = currentX;
|
||||
_bumpTargetX = targetX;
|
||||
_bumpDuration = 0.5f; // Fixed duration for impulse
|
||||
|
||||
StartBump();
|
||||
|
||||
Debug.Log($"[PlayerBumpCollisionBehavior] Starting impulse bump from X={_bumpStartX} to X={_bumpTargetX} (force={bumpForce})");
|
||||
}
|
||||
|
||||
/// <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);
|
||||
|
||||
// Set bump parameters
|
||||
_bumpStartX = currentX;
|
||||
_bumpTargetX = 0f; // Always move to center
|
||||
_bumpDuration = distanceToCenter / smoothMoveSpeed; // Duration based on distance and speed
|
||||
|
||||
StartBump();
|
||||
|
||||
Debug.Log($"[PlayerBumpCollisionBehavior] Starting smooth move to center from X={_bumpStartX} (speed={smoothMoveSpeed}, duration={_bumpDuration:F2}s)");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Common bump initialization
|
||||
/// </summary>
|
||||
private void StartBump()
|
||||
{
|
||||
_isBumping = true;
|
||||
_bumpTimer = _bumpDuration;
|
||||
|
||||
// Block player input if enabled (use bump-specific blocking)
|
||||
if (blockInputDuringBump && playerController != null && playerController.enabled)
|
||||
{
|
||||
playerController.enabled = false;
|
||||
_bumpInputBlocked = true;
|
||||
Debug.Log("[PlayerBumpCollisionBehavior] Player input blocked during bump");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores player input after bump movement
|
||||
/// </summary>
|
||||
private void RestoreBumpInput()
|
||||
{
|
||||
if (_bumpInputBlocked && playerController != null)
|
||||
{
|
||||
playerController.enabled = true;
|
||||
_bumpInputBlocked = false;
|
||||
|
||||
// Update the controller's target position to current position to prevent snapping
|
||||
UpdateControllerTarget();
|
||||
|
||||
Debug.Log("[PlayerBumpCollisionBehavior] Player input restored after bump");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnImmunityEnd()
|
||||
{
|
||||
base.OnImmunityEnd();
|
||||
|
||||
// Stop any ongoing bump if immunity ends
|
||||
if (_isBumping)
|
||||
{
|
||||
_isBumping = false;
|
||||
if (_bumpInputBlocked)
|
||||
{
|
||||
RestoreBumpInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public method to change bump mode at runtime
|
||||
/// </summary>
|
||||
public void SetBumpMode(BumpMode mode)
|
||||
{
|
||||
bumpMode = mode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public method to change bump force at runtime
|
||||
/// </summary>
|
||||
public void SetBumpForce(float force)
|
||||
{
|
||||
bumpForce = force;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Public method to change smooth move speed at runtime
|
||||
/// </summary>
|
||||
public void SetSmoothMoveSpeed(float speed)
|
||||
{
|
||||
smoothMoveSpeed = speed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if player is currently being bumped
|
||||
/// </summary>
|
||||
public bool IsBumping => _isBumping;
|
||||
|
||||
/// <summary>
|
||||
/// Check if input is currently blocked by bump
|
||||
/// </summary>
|
||||
public bool IsBumpInputBlocked => _bumpInputBlocked;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user