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(); } if (theWaltzOfTheSword == null) { theWaltzOfTheSword = combatPlayerController.MainSkillObject.GetComponent(); } 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; } } }