158 lines
6.1 KiB
C#
158 lines
6.1 KiB
C#
using UnityEngine;
|
|
using AppleHills.Core.Settings;
|
|
|
|
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
|
|
{
|
|
// Settings reference
|
|
private IDivingMinigameSettings _settings;
|
|
|
|
private float _targetFingerX;
|
|
private bool _isTouchActive;
|
|
private float _originY;
|
|
|
|
// Tap impulse system variables
|
|
private float _tapImpulseStrength = 0f;
|
|
private float _tapDirection = 0f;
|
|
|
|
void Awake()
|
|
{
|
|
_originY = transform.position.y;
|
|
|
|
// Get settings from GameManager
|
|
_settings = GameManager.GetSettingsObject<IDivingMinigameSettings>();
|
|
if (_settings == null)
|
|
{
|
|
Debug.LogError("[PlayerController] Failed to load diving minigame settings!");
|
|
}
|
|
}
|
|
|
|
void Start()
|
|
{
|
|
// Register as default consumer for input
|
|
InputManager.Instance?.SetDefaultConsumer(this);
|
|
// Initialize target to current position
|
|
_targetFingerX = transform.position.x;
|
|
_isTouchActive = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles tap input. Applies an impulse in the tapped direction.
|
|
/// </summary>
|
|
public void OnTap(Vector2 worldPosition)
|
|
{
|
|
// Debug.Log($"[EndlessDescenderController] OnTap at {worldPosition}");
|
|
float targetX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
|
|
|
// 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
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles the start of a hold input. Begins tracking the finger.
|
|
/// </summary>
|
|
public void OnHoldStart(Vector2 worldPosition)
|
|
{
|
|
// Debug.Log($"[EndlessDescenderController] OnHoldStart at {worldPosition}");
|
|
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
|
_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}");
|
|
_targetFingerX = Mathf.Clamp(worldPosition.x, _settings.ClampXMin, _settings.ClampXMax);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles the end of a hold input. Stops tracking.
|
|
/// </summary>
|
|
public void OnHoldEnd(Vector2 worldPosition)
|
|
{
|
|
// Debug.Log($"[EndlessDescenderController] OnHoldEnd at {worldPosition}");
|
|
_isTouchActive = false;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// Handle hold movement
|
|
if (_isTouchActive)
|
|
{
|
|
float currentX = transform.position.x;
|
|
float lerpSpeed = _settings.LerpSpeed;
|
|
float maxOffset = _settings.MaxOffset;
|
|
float exponent = _settings.SpeedExponent;
|
|
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;
|
|
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
|
|
|
|
UpdatePosition(newX);
|
|
}
|
|
// Handle tap impulse movement
|
|
else if (_tapImpulseStrength > 0)
|
|
{
|
|
float currentX = transform.position.x;
|
|
float maxOffset = _settings.MaxOffset;
|
|
float lerpSpeed = _settings.LerpSpeed;
|
|
|
|
// Calculate move distance based on impulse strength
|
|
float moveDistance = maxOffset * _tapImpulseStrength * Time.deltaTime * lerpSpeed;
|
|
|
|
// Limit total movement from single tap
|
|
moveDistance = Mathf.Min(moveDistance, _settings.TapMaxDistance * _tapImpulseStrength);
|
|
|
|
// Apply movement in tap direction
|
|
float newX = currentX + (moveDistance * _tapDirection);
|
|
newX = Mathf.Clamp(newX, _settings.ClampXMin, _settings.ClampXMax);
|
|
|
|
// Reduce impulse strength over time
|
|
_tapImpulseStrength -= Time.deltaTime * _settings.TapDecelerationRate;
|
|
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)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
} |