AttackState.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik //
  2. #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value.
  3. using UnityEngine;
  4. namespace Animancer.Examples.StateMachines
  5. {
  6. /// <summary>A <see cref="CharacterState"/> which can perform <see cref="Weapon.AttackAnimations"/> in sequence.</summary>
  7. /// <example><see href="https://kybernetik.com.au/animancer/docs/examples/fsm/weapons">Weapons</see></example>
  8. /// https://kybernetik.com.au/animancer/api/Animancer.Examples.StateMachines/AttackState
  9. ///
  10. [AddComponentMenu(Strings.ExamplesMenuPrefix + "Weapons - Attack State")]
  11. [HelpURL(Strings.DocsURLs.ExampleAPIDocumentation + nameof(StateMachines) + "/" + nameof(AttackState))]
  12. public sealed class AttackState : CharacterState
  13. {
  14. /************************************************************************************************************************/
  15. private int _AttackIndex = int.MaxValue;
  16. public Weapon Weapon => Character.Equipment.Weapon;
  17. /************************************************************************************************************************/
  18. public override bool CanEnterState =>
  19. Weapon != null &&
  20. Weapon.AttackAnimations.Length > 0;
  21. /************************************************************************************************************************/
  22. /// <summary>
  23. /// Start at the beginning of the sequence by default, but if the previous attack has not faded out yet then
  24. /// perform the next attack instead.
  25. /// </summary>
  26. private void OnEnable()
  27. {
  28. if (ShouldRestartCombo())
  29. {
  30. _AttackIndex = 0;
  31. }
  32. else
  33. {
  34. _AttackIndex++;
  35. }
  36. var animation = Weapon.AttackAnimations[_AttackIndex];
  37. animation.Events.OnEnd = Character.StateMachine.ForceSetDefaultState;
  38. Character.Animancer.Play(animation);
  39. }
  40. /************************************************************************************************************************/
  41. private bool ShouldRestartCombo()
  42. {
  43. var attackAnimations = Weapon.AttackAnimations;
  44. if (_AttackIndex >= attackAnimations.Length - 1)
  45. return true;
  46. var state = attackAnimations[_AttackIndex].State;
  47. if (state == null ||
  48. state.Weight == 0)
  49. return true;
  50. return false;
  51. }
  52. /************************************************************************************************************************/
  53. public override CharacterStatePriority Priority => CharacterStatePriority.Medium;
  54. /************************************************************************************************************************/
  55. }
  56. }