CapersProject/Assets/02.Scripts/Character/Player/Combat/CombatMovement.cs

252 lines
7.6 KiB
C#
Raw Normal View History

2024-06-03 18:26:03 +00:00
using System;
using System.Collections;
using BlueWater.Audios;
using BlueWater.Interfaces;
using BlueWater.Utility;
using UnityEngine;
namespace BlueWater.Players.Combat
{
public class CombatMovement : MonoBehaviour, IDashable, IPhysicMovable
{
// Variables
#region Variables
// Components
public Rigidbody Rigidbody { get; private set; }
private Transform _visualLook;
private AnimationController _animationController;
// Move
[field: SerializeField, Range(1f, 10f), Tooltip("이동 속도")]
public float MoveSpeed { get; private set; } = 7f;
public bool EnableMove { get; private set; } = true;
private bool _isMoving;
public bool IsMoving
{
get => _isMoving;
set
{
_isMoving = value;
_animationController.SetAnimationParameter("isMoving", _isMoving);
}
}
private Vector3 _inputDirection;
private Vector3 _currentDirection = Vector3.back;
public Vector3 CurrentDirection
{
get => _currentDirection;
set
{
if (value == Vector3.zero) return;
_currentDirection = value;
_animationController.SetAnimationParameter("xDirection", _currentDirection.x);
_animationController.SetAnimationParameter("zDirection", _currentDirection.z);
}
}
private float _finalSpeed;
private float _moveSpeedCoefficient = 1f;
// Dash
[field: SerializeField, Range(1f, 50f), Tooltip("대쉬 속도")]
public float DashSpeed { get; private set; } = 20f;
[field: SerializeField, Range(0.1f, 1f), Tooltip("대쉬 시간")]
public float DashTime { get; private set; } = 0.2f;
[field: SerializeField, Range(0f, 5f), Tooltip("대쉬 쿨타임")]
public float DashCooldown { get; private set; } = 0.5f;
public bool EnableDash { get; private set; } = true;
private bool _isDashing;
public bool IsDashing
{
get => _isDashing;
private set
{
_isDashing = value;
_animationController.SetAnimationParameter("isDashing", _isDashing);
}
}
public bool IsDashCoolDownActive { get; private set; }
private Coroutine _dashCoroutine;
// Events
public event Action OnStartDash;
public event Action OnEndDash;
#endregion
// Unity events
#region Unity events
private void Update()
{
FlipVisualLook();
}
private void FixedUpdate()
{
if (!CanMove()) return;
ApplyMovement();
}
#endregion
// Initialize Methods
#region Initialize Methods
public void InitializeComponents(Rigidbody rigidbody, Transform visualLook, AnimationController animationController)
{
Rigidbody = rigidbody;
_visualLook = visualLook;
_animationController = animationController;
}
#endregion
// Methods
#region Methods
// Event methods
public void HandleInputMovement(Vector2 movementInput)
{
_inputDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
}
public void HandleAttackInDash()
{
if (IsDashing)
{
EndDash(DashCooldown);
}
}
public void HandleMoveSpeedCoefficient(float value) => _moveSpeedCoefficient = value;
public void HandleResetMoveSpeedCoefficient() => _moveSpeedCoefficient = 1f;
public void HandleEnableMove() => EnableMove = true;
public void HandleDisableMove() => EnableMove = false;
public void HandleEnableDash() => EnableDash = true;
public void HandleDisableDash() => EnableDash = false;
public void HandleEnableMoveAndDash()
{
EnableMove = true;
EnableDash = true;
}
public void HandleDisableMoveAndDash()
{
EnableMove = false;
EnableDash = false;
}
// Methods
private void FlipVisualLook()
{
var localScale = _visualLook.localScale;
localScale.x = CurrentDirection.x switch
{
> 0.01f => Mathf.Abs(localScale.x),
< -0.01f => -Mathf.Abs(localScale.x),
_ => localScale.x
};
_visualLook.localScale = localScale;
}
// Move
public bool CanMove()
{
return EnableMove && !IsDashing;
}
public void AddForce(Vector3 force, ForceMode forceMode)
{
if (_isDashing) return;
Rigidbody.AddForce(force, forceMode);
}
private void ApplyMovement()
{
CurrentDirection = _inputDirection;
IsMoving = _inputDirection != Vector3.zero;
// var finalVelocity = _inputDirection * (MoveSpeed * _moveSpeedCoefficient);
// Rigidbody.linearVelocity = finalVelocity;
var finalVelocity = _inputDirection * (MoveSpeed * _moveSpeedCoefficient * Time.deltaTime);
Rigidbody.MovePosition(transform.position + finalVelocity);
}
// Dash
public bool CanDash()
{
return EnableMove && EnableDash && !IsDashing && !IsDashCoolDownActive;
}
public void HandleDash()
{
if (!CanDash()) return;
Utils.StartUniqueCoroutine(this, ref _dashCoroutine, DashCoroutine());
}
private IEnumerator DashCoroutine()
{
OnStartDash?.Invoke();
IsDashing = true;
IsDashCoolDownActive = true;
var dashDirection = CurrentDirection;
var animationStarted = false;
yield return StartCoroutine(_animationController.WaitForAnimationToRun("DashState",
success => animationStarted = success));
if (!animationStarted)
{
EndDash(0);
yield break;
}
_animationController.SetCurrentAnimationSpeed(DashTime);
AudioManager.Instance.PlaySfx("CombatPlayerDash");
while (_animationController.IsComparingCurrentAnimation("DashState") &&
_animationController.GetCurrentAnimationNormalizedTime() < 1f)
{
//var finalVelocity = rb.position + dashDirection * (dashSpeed * Time.fixedDeltaTime);
//rb.MovePosition(finalVelocity);
var finalVelocity = dashDirection * DashSpeed;
Rigidbody.linearVelocity = finalVelocity;
yield return new WaitForFixedUpdate();
}
EndDash(DashCooldown);
}
public void EndDash(float dashCooldown)
{
Utils.EndUniqueCoroutine(this, ref _dashCoroutine);
Rigidbody.linearVelocity = Vector3.zero;
_animationController.ResetAnimationSpeed();
OnEndDash?.Invoke();
IsDashing = false;
StartCoroutine(Utils.CoolDownCoroutine(dashCooldown, () => IsDashCoolDownActive = false));
}
#endregion
}
}