OldBlueWater/BlueWater/Assets/02.Scripts/Character/CombatPlayer/StateMachines/TheWaltzOfTheSwordBehavior.cs

173 lines
5.9 KiB
C#

using System;
using System.Linq;
using UnityEngine;
// ReSharper disable once CheckNamespace
namespace BlueWaterProject
{
public class TheWaltzOfTheSwordBehavior : StateMachineBehaviour
{
private enum Direction
{
NONE = -1,
LEFT,
BACK,
RIGHT
}
private CombatPlayerController combatPlayerController;
private TheWaltzOfTheSword theWaltzOfTheSword;
private int currentHitNum;
private int hitCount;
private float time;
private float intervalTime;
private Direction currentDirection;
private bool previousLeft;
private bool isMoved;
public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
if (combatPlayerController == null)
{
combatPlayerController = animator.GetComponentInParent<CombatPlayerController>();
}
if (theWaltzOfTheSword == null)
{
theWaltzOfTheSword = combatPlayerController.MainSkillObject.GetComponent<TheWaltzOfTheSword>();
}
var animationLength = stateInfo.length;
animator.speed = animationLength / theWaltzOfTheSword.SkillDuration;
intervalTime = animationLength / animator.speed / 6f;
if (!theWaltzOfTheSword.isMovingCamera)
{
CameraManager.Inst.CombatCamera.SetFollowAndLookAt(null);
}
combatPlayerController.SetUseGravity(false);
combatPlayerController.SetIsTrigger(true);
combatPlayerController.SetIsInvincibility(true);
currentDirection = Direction.BACK;
previousLeft = false;
isMoved = false;
currentHitNum = 0;
hitCount = 0;
time = 0f;
}
public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
time += Time.deltaTime;
if (hitCount < 6)
{
if (!isMoved)
{
MovePoint(theWaltzOfTheSword.HitColliders[currentHitNum], currentDirection);
}
else if (time >= intervalTime)
{
ExecuteAttackRoutine(animator);
}
}
// 모든 공격 시퀀스가 완료된 경우
if (hitCount >= 6)
{
animator.SetBool(CombatPlayerController.IsActivateMainSkillHash, false);
}
}
public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.speed = 1f;
if (theWaltzOfTheSword.returnToStartPosition)
{
combatPlayerController.Move(theWaltzOfTheSword.SkillInputData.StartPosition);
}
if (!theWaltzOfTheSword.isMovingCamera)
{
var userTransform = theWaltzOfTheSword.SkillInputData.PlayerCollider.transform;
CameraManager.Inst.CombatCamera.SetFollowAndLookAt(userTransform);
}
combatPlayerController.SetIsTrigger(false);
combatPlayerController.SetUseGravity(true);
combatPlayerController.SetIsInvincibility(false);
combatPlayerController.SetEnableMoving(true);
}
private void ExecuteAttackRoutine(Animator animator)
{
theWaltzOfTheSword.SkillAttackTiming(theWaltzOfTheSword.HitColliders[currentHitNum]);
hitCount++;
AddCurrentNum();
for (var i = 0; i < theWaltzOfTheSword.HitSize; i++)
{
if (!theWaltzOfTheSword.IsTargetAlive(theWaltzOfTheSword.HitColliders[currentHitNum]))
{
AddCurrentNum();
continue;
}
isMoved = false;
time = 0f;
return;
}
animator.SetBool(CombatPlayerController.IsActivateMainSkillHash, false);
}
private void AddCurrentNum()
{
currentHitNum = (currentHitNum + 1) % theWaltzOfTheSword.HitSize;
}
private void MovePoint(Collider hitCollider, Direction direction)
{
var center = hitCollider.bounds.center;
var addX = 0f;
var addZ = 0f;
switch(direction)
{
case Direction.NONE:
break;
case Direction.LEFT:
combatPlayerController.SetPreviousMoveDirection(Vector3.right);
addX = -hitCollider.bounds.extents.x;
currentDirection = Direction.BACK;
break;
case Direction.BACK:
addZ = hitCollider.bounds.extents.z;
if (previousLeft)
{
currentDirection = Direction.RIGHT;
}
else
{
currentDirection = Direction.LEFT;
}
previousLeft = !previousLeft;
break;
case Direction.RIGHT:
combatPlayerController.SetPreviousMoveDirection(Vector3.left);
addX = hitCollider.bounds.extents.x;
currentDirection = Direction.BACK;
break;
default:
throw new ArgumentOutOfRangeException(nameof(direction), direction, null);
}
var newPosition = new Vector3(center.x + addX, combatPlayerController.transform.position.y, center.z + addZ);
combatPlayerController.Move(newPosition);
isMoved = true;
}
}
}