107 lines
3.1 KiB
C#
107 lines
3.1 KiB
C#
using UnityEngine;
|
|
using Unheimlich.Interactions.Core;
|
|
using Unheimlich.Data.CameraSettings;
|
|
|
|
namespace Unheimlich.Gameplay.Player
|
|
{
|
|
/// <summary>
|
|
/// Simulates camera head bobbing motion during player movement and idle states.
|
|
/// Applies subtle oscillation based on player grounded and movement state.
|
|
/// </summary>
|
|
public class CameraHeadBob : MonoBehaviour
|
|
{
|
|
[Header("Bob Settings - Idle")]
|
|
[SerializeField] private float _idleBobSpeed = 1f;
|
|
[SerializeField] private float _idleBobAmplitude = 0.005f;
|
|
|
|
[Header("Bob Settings - Walk")]
|
|
[SerializeField] private float _walkBobSpeed = 12f;
|
|
[SerializeField] private float _walkBobAmplitude = 0.02f;
|
|
[SerializeField] private float _resetSpeed = 5f;
|
|
|
|
private PlayerMovement _playerMovement;
|
|
private float _timer = 0f;
|
|
private Vector3 _startLocalPos;
|
|
|
|
private HeadBobMode _overrideMode = HeadBobMode.Normal;
|
|
private bool _hasOverride = false;
|
|
|
|
void Start()
|
|
{
|
|
_playerMovement = PlayerMovement.Instance;
|
|
_startLocalPos = transform.localPosition;
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
if (_playerMovement == null || _playerMovement.CharacterController == null)
|
|
return;
|
|
|
|
HeadBobMode currentMode = _hasOverride ? _overrideMode : HeadBobMode.Normal;
|
|
|
|
if (currentMode == HeadBobMode.Disabled)
|
|
{
|
|
ResetPosition();
|
|
return;
|
|
}
|
|
|
|
if (currentMode == HeadBobMode.Idle || (PlayerInspectionHandler.Instance != null && PlayerInspectionHandler.Instance.IsInspecting))
|
|
{
|
|
ApplyBob(_idleBobSpeed, _idleBobAmplitude);
|
|
return;
|
|
}
|
|
|
|
bool isMoving = _playerMovement.IsMoving;
|
|
bool isGrounded = _playerMovement.CharacterController.isGrounded;
|
|
|
|
if (isGrounded)
|
|
{
|
|
if (isMoving)
|
|
ApplyBob(_walkBobSpeed, _walkBobAmplitude);
|
|
else
|
|
ApplyBob(_idleBobSpeed, _idleBobAmplitude);
|
|
}
|
|
else
|
|
ResetPosition();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the head bob mode override.
|
|
/// </summary>
|
|
public void SetMode(HeadBobMode mode)
|
|
{
|
|
_overrideMode = mode;
|
|
_hasOverride = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the override and returns to normal behavior.
|
|
/// </summary>
|
|
public void ClearOverride()
|
|
{
|
|
_hasOverride = false;
|
|
}
|
|
|
|
private void ApplyBob(float speed, float amplitude)
|
|
{
|
|
_timer += Time.deltaTime * speed;
|
|
|
|
float x = Mathf.Sin(_timer * 0.5f) * amplitude;
|
|
float y = Mathf.Cos(_timer) * amplitude;
|
|
|
|
Vector3 newPos = _startLocalPos;
|
|
newPos.x += x;
|
|
newPos.y += y;
|
|
|
|
transform.localPosition = newPos;
|
|
}
|
|
|
|
private void ResetPosition()
|
|
{
|
|
transform.localPosition = Vector3.Lerp(transform.localPosition, _startLocalPos, Time.deltaTime * _resetSpeed);
|
|
|
|
if (Vector3.Distance(transform.localPosition, _startLocalPos) < 0.001f)
|
|
_timer = 0f;
|
|
}
|
|
}
|
|
} |