OldBlueWater/BlueWater/Assets/02.Scripts/Character/CombatPlayer2D/CombatMovement.cs
NTG f1d0c6d371 Closes #244, #254 CombatPlayer 개선, 하트 시스템 추가
+ CombatPlayer 기능별 분리
+ Combat, CombatUi 전용 input action map 추가
+ 스킬 시스템 로직 수정
+ 전투플레이어 스킬(검의 왈츠) 로직 변경
2024-05-08 00:37:33 +09:00

234 lines
7.0 KiB
C#

using System.Collections;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class CombatMovement : MonoBehaviour, IRigidMovable, IDashable
{
// Components
public Rigidbody Rb { get; set; }
private Transform visualLook;
// Move
[Range(1f, 10f), Tooltip("이동 속도")]
[SerializeField] private float moveSpeed = 7f;
// Dash
[field: Range(1f, 50f), Tooltip("대쉬 속도")]
[field: SerializeField] public float DashSpeed { get; set; } = 20f;
[field: Range(0.1f, 1f), Tooltip("대쉬 시간")]
[field: SerializeField] public float DashTime { get; set; } = 0.2f;
[field: Range(0f, 5f), Tooltip("대쉬 쿨타임")]
[field: SerializeField] public float DashCooldown { get; set; } = 0.5f;
public bool EnableDash { get; set; } = true;
private bool isDashing;
public bool IsDashing
{
get => isDashing;
set
{
isDashing = value;
iAnimationStateController.SetAnimationParameter(CombatPlayerAnimatorParameter.IS_DASHING, IsDashing);
}
}
// Interfaces
private IAnimationStateController iAnimationStateController;
private IMeleeComboAttackable iMeleeComboAttackable;
// Variables
private Vector3 currentMoveDirection;
private Vector3 previousMoveDirection = Vector3.back;
public Vector3 PreviousMoveDirection
{
get => previousMoveDirection;
set
{
previousMoveDirection = value;
iAnimationStateController.SetAnimationParameter(CombatPlayerAnimatorParameter.X_DIRECTION, PreviousMoveDirection.x);
iAnimationStateController.SetAnimationParameter(CombatPlayerAnimatorParameter.Z_DIRECTION, PreviousMoveDirection.z);
}
}
private Coroutine dashCoroutine;
private float finalSpeed;
private bool isMoving;
public bool IsMoving
{
get => isMoving;
set
{
isMoving = value;
iAnimationStateController.SetAnimationParameter(CombatPlayerAnimatorParameter.IS_MOVING, isMoving);
}
}
public bool EnableMove { get; set; } = true;
// Events
public delegate void StartDashEvent();
public event StartDashEvent OnStartDash;
public delegate void EndDashEvent();
public event EndDashEvent OnEndDash;
// Unity events
private void Start()
{
iAnimationStateController = GetComponent<IAnimationStateController>();
iMeleeComboAttackable = GetComponent<IMeleeComboAttackable>();
}
private void Update()
{
FlipVisualLook();
}
private void FixedUpdate()
{
if (!EnableMove || IsDashing) return;
ApplyMovement();
}
// Init
public void InitComponent(Rigidbody rb, Transform visualLook)
{
Rb = rb;
this.visualLook = visualLook;
}
// Event methods
public void HandleInputMovement(Vector2 movementInput)
{
currentMoveDirection = new Vector3(movementInput.x, 0, movementInput.y).normalized;
}
public void HandleDash()
{
if (!CanMove()) return;
if (iMeleeComboAttackable.CurrentComboAttackCount > 0)
{
iMeleeComboAttackable.EndComboAttack();
}
dashCoroutine = StartCoroutine(nameof(DashCoroutine));
}
public void HandleAttackInDash()
{
if (IsDashing)
{
EndDash(DashCooldown);
}
}
public void HandleEnableMove() => EnableMove = true;
public void HandleDisableMove() => EnableMove = 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 = PreviousMoveDirection.x switch
{
> 0.01f => Mathf.Abs(localScale.x),
< -0.01f => -Mathf.Abs(localScale.x),
_ => localScale.x
};
visualLook.localScale = localScale;
}
private void ApplyMovement()
{
if (currentMoveDirection != Vector3.zero)
{
PreviousMoveDirection = currentMoveDirection;
}
IsMoving = currentMoveDirection != Vector3.zero;
var finalVelocity = currentMoveDirection * moveSpeed;
Rb.velocity = finalVelocity;
}
private bool CanMove()
{
return EnableDash && !IsDashing;
}
private IEnumerator DashCoroutine()
{
StartDash();
var dashDirection = PreviousMoveDirection;
var animationStarted = false;
yield return StartCoroutine(iAnimationStateController.WaitForAnimationToRun(CombatPlayerAnimationName.DASH_STATE,
success => animationStarted = success));
if (!animationStarted)
{
EndDash(0);
yield break;
}
iAnimationStateController.SetCurrentAnimationSpeed(DashTime);
while (iAnimationStateController.IsComparingCurrentAnimation(CombatPlayerAnimationName.DASH_STATE) &&
iAnimationStateController.GetCurrentAnimationNormalizedTime() < 1f)
{
//var finalVelocity = rb.position + dashDirection * (dashSpeed * Time.fixedDeltaTime);
//rb.MovePosition(finalVelocity);
var finalVelocity = dashDirection * DashSpeed;
Rb.velocity = finalVelocity;
yield return new WaitForFixedUpdate();
}
EndDash(DashCooldown);
}
private void StartDash()
{
OnStartDash?.Invoke();
EnableDash = false;
IsDashing = true;
}
public void EndDash(float dashCooldown)
{
if (dashCoroutine != null)
{
StopCoroutine(dashCoroutine);
dashCoroutine = null;
}
Rb.velocity = Vector3.zero;
iAnimationStateController.ResetAnimationSpeed();
OnEndDash?.Invoke();
IsDashing = false;
StartCoroutine(Utils.CoolDown(dashCooldown, () => EnableDash = true));
}
}
}