protected override void OnStateExit(RangedAIState state) { switch (state) { case RangedAIState.Idle: { Animator.SetTrigger("Combat"); } break; case RangedAIState.Strafe: { _strafeElapsedCooldown = 0f; _strafeElapsedTime = 0f; _attackRequestElapsedCooldown = 0f; } break; case RangedAIState.Attack: { AttackTarget.SendMessage("CompleteAttack", gameObject); } break; case RangedAIState.Hit: { RVOController.locked = false; } break; } }
protected override void OnStateEnter(MeleeAIState state) { switch (state) { case MeleeAIState.Idle: { } break; case MeleeAIState.Strafe: { _strafeDir = Random.value > 0.5f ? 1f : -1f; //Animator.SetFloat(AnimatorHash.VelocityX, 0f); //Animator.SetFloat(AnimatorHash.VelocityZ, 0f); } break; case MeleeAIState.Rush: { } break; case MeleeAIState.Attack: { Animator.SetTrigger(AnimatorHash.Attack); } break; case MeleeAIState.Hit: { AttackTarget.SendMessage("CompleteAttack", gameObject); RVOController.locked = true; if (IsDead) { CurrentState = MeleeAIState.Dead; } } break; } }
protected override void OnStateUpdate(MeleeAIState state) { switch (state) { case MeleeAIState.Strafe: { Vector3 diff = AttackTarget.position - transform.position; Vector3 dir = diff; dir.y = 0f; float sqrDist = diff.sqrMagnitude; if (sqrDist > _strafeRange * _strafeRange) { // Move To Target Move(dir, _strafeSpeed); } else { // Request Attack if (_attackRequestElapsedCooldown < _attackRequestCooldown) { _attackRequestElapsedCooldown += Timer.Delta; if (_attackRequestElapsedCooldown >= _attackRequestCooldown) { AttackTarget.SendMessage("RequestAttack", gameObject); _attackRequestElapsedCooldown = 0f; } } // Random Strafe / Step Back if (_strafeElapsedCooldown < _strafeCooldown) { if (_isBackwards) { float range = Mathf.Min(_strafeRange, _dangerRange + 0.5f); if (sqrDist <= range * range) { Move(-dir, _strafeSpeed * 0.5f); } else { _isBackwards = false; } } else if (sqrDist > _dangerRange * _dangerRange) { _strafeElapsedCooldown += Timer.Delta; if (_strafeElapsedCooldown >= _strafeCooldown) { _strafeDir = Random.value > 0.5f ? 1f : -1f; _strafeElapsedTime = _strafeElapsedTime < _strafeTime ? _strafeTime - _strafeElapsedTime : 0f; _strafeElapsedCooldown = 0f; } if (_strafeElapsedTime < _strafeTime) { Vector3 moveDir = _strafeDir * (Quaternion.AngleAxis(75f, AttackTarget.up) * dir); Move(moveDir, _strafeSpeed); _strafeElapsedTime += Timer.Delta; } } else { _isBackwards = true; } } } Rotate(Quaternion.LookRotation(dir), _strafeRotateSpeed); Vector3 velocity = transform.InverseTransformVector(Velocity); Animator.SetFloat(AnimatorHash.VelocityX, Mathf.Min(velocity.x, _strafeSpeed), 0.1f, Timer.Delta); Animator.SetFloat(AnimatorHash.VelocityZ, Mathf.Min(velocity.z, _strafeSpeed), 0.1f, Timer.Delta); } break; case MeleeAIState.Rush: { Vector3 diff = AttackTarget.position - transform.position; Vector3 dir = diff; dir.y = 0f; if (diff.sqrMagnitude > _attackRange * _attackRange) { Move(dir, _rushSpeed); } else { CurrentState = MeleeAIState.Attack; } Rotate(Quaternion.LookRotation(dir), _rushRotateSpeed); Vector3 velocity = transform.InverseTransformVector(Velocity); Animator.SetFloat(AnimatorHash.VelocityX, Mathf.Min(velocity.x, _rushSpeed), 0.1f, Timer.Delta); Animator.SetFloat(AnimatorHash.VelocityZ, Mathf.Min(velocity.z, _rushSpeed), 0.1f, Timer.Delta); } break; } }