Files
AppleHillsProduction/Assets/Scripts/Minigames/DivingForPictures/Player/PlayerController.cs

158 lines
6.1 KiB
C#
Raw Normal View History

2025-09-10 09:36:15 +02:00
using UnityEngine;
2025-09-24 12:21:21 +02:00
using AppleHills.Core.Settings;
2025-09-10 09:36:15 +02:00
namespace Minigames.DivingForPictures
{
/// <summary>
/// Handles endless descender movement in response to tap and hold input events.
/// Moves the character horizontally to follow the finger or tap position.
/// </summary>
public class PlayerController : MonoBehaviour, ITouchInputConsumer
{
2025-09-24 12:21:21 +02:00
// Settings reference
private IDivingMinigameSettings _settings;
2025-09-22 15:01:53 +02:00
2025-09-10 09:36:15 +02:00
private float _targetFingerX;
private bool _isTouchActive;
private float _originY;
2025-09-22 15:01:53 +02:00
// Tap impulse system variables
private float _tapImpulseStrength = 0f;
private float _tapDirection = 0f;
2025-09-10 09:36:15 +02:00
void Awake()
{
_originY = transform.position.y;
2025-09-24 12:21:21 +02:00
// Get settings from GameManager
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
if (_settings == null)
{
Debug.LogError("[PlayerController] Failed to load diving minigame settings!");
}
2025-09-10 09:36:15 +02:00
}
void Start()
{
// Register as default consumer for input
InputManager.Instance?.SetDefaultConsumer(this);
// Initialize target to current position
_targetFingerX = transform.position.x;
_isTouchActive = false;
}
/// <summary>
2025-09-22 15:01:53 +02:00
/// Handles tap input. Applies an impulse in the tapped direction.
2025-09-10 09:36:15 +02:00
/// </summary>
public void OnTap(Vector2 worldPosition)
{
// Debug.Log($"[EndlessDescenderController] OnTap at {worldPosition}");
2025-09-24 15:16:31 +02:00
float targetX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
2025-09-22 15:01:53 +02:00
// Calculate tap direction (+1 for right, -1 for left)
_tapDirection = Mathf.Sign(targetX - transform.position.x);
// Set impulse strength to full
_tapImpulseStrength = 1.0f;
// Store target X for animation purposes
_targetFingerX = targetX;
// Do not set _isTouchActive for taps anymore
// _isTouchActive = true; - Removed to prevent continuous movement
2025-09-10 09:36:15 +02:00
}
/// <summary>
/// Handles the start of a hold input. Begins tracking the finger.
/// </summary>
public void OnHoldStart(Vector2 worldPosition)
{
// Debug.Log($"[EndlessDescenderController] OnHoldStart at {worldPosition}");
2025-09-24 15:16:31 +02:00
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
2025-09-10 09:36:15 +02:00
_isTouchActive = true;
}
/// <summary>
/// Handles hold move input. Updates the target X position as the finger moves.
/// </summary>
public void OnHoldMove(Vector2 worldPosition)
{
// Debug.Log($"[EndlessDescenderController] OnHoldMove at {worldPosition}");
2025-09-24 15:16:31 +02:00
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
2025-09-10 09:36:15 +02:00
}
/// <summary>
/// Handles the end of a hold input. Stops tracking.
/// </summary>
public void OnHoldEnd(Vector2 worldPosition)
{
// Debug.Log($"[EndlessDescenderController] OnHoldEnd at {worldPosition}");
2025-09-10 09:36:15 +02:00
_isTouchActive = false;
}
void Update()
{
2025-09-22 15:01:53 +02:00
// Handle hold movement
if (_isTouchActive)
{
float currentX = transform.position.x;
2025-09-24 15:16:31 +02:00
float lerpSpeed = _settings.LerpSpeed;
float maxOffset = _settings.MaxOffset;
float exponent = _settings.SpeedExponent;
2025-09-22 15:01:53 +02:00
float targetX = _targetFingerX;
float offset = targetX - currentX;
offset = Mathf.Clamp(offset, -maxOffset, maxOffset);
float absOffset = Mathf.Abs(offset);
float t = Mathf.Pow(absOffset / maxOffset, exponent); // Non-linear drop-off
float moveStep = Mathf.Sign(offset) * maxOffset * t * Time.deltaTime * lerpSpeed;
// Prevent overshooting
moveStep = Mathf.Clamp(moveStep, -absOffset, absOffset);
float newX = currentX + moveStep;
2025-09-24 15:16:31 +02:00
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
2025-09-22 15:01:53 +02:00
UpdatePosition(newX);
}
// Handle tap impulse movement
else if (_tapImpulseStrength > 0)
{
float currentX = transform.position.x;
2025-09-24 15:16:31 +02:00
float maxOffset = _settings.MaxOffset;
float lerpSpeed = _settings.LerpSpeed;
2025-09-22 15:01:53 +02:00
// Calculate move distance based on impulse strength
float moveDistance = maxOffset * _tapImpulseStrength * Time.deltaTime * lerpSpeed;
// Limit total movement from single tap
2025-09-24 15:16:31 +02:00
moveDistance = Mathf.Min(moveDistance, _settings.TapMaxDistance * _tapImpulseStrength);
2025-09-22 15:01:53 +02:00
// Apply movement in tap direction
float newX = currentX + (moveDistance * _tapDirection);
2025-09-24 15:16:31 +02:00
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
2025-09-22 15:01:53 +02:00
// Reduce impulse strength over time
2025-09-24 15:16:31 +02:00
_tapImpulseStrength -= Time.deltaTime * _settings.TapDecelerationRate;
2025-09-22 15:01:53 +02:00
if (_tapImpulseStrength < 0.01f)
{
_tapImpulseStrength = 0f;
}
UpdatePosition(newX);
}
}
/// <summary>
/// Updates the player's position with the given X coordinate
/// </summary>
private void UpdatePosition(float newX)
{
2025-09-10 09:36:15 +02:00
float newY = _originY;
// Add vertical offset from WobbleBehavior if present
WobbleBehavior wobble = GetComponent<WobbleBehavior>();
if (wobble != null)
{
newY += wobble.VerticalOffset;
}
transform.position = new Vector3(newX, newY, transform.position.z);
}
}
}