// Animancer // https://kybernetik.com.au/animancer // Copyright 2022 Kybernetik // #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value. using Animancer.Units; using UnityEngine; namespace Animancer.Examples.Events { /// Manages a character with the ability to hit a golf ball. /// Golf Events /// https://kybernetik.com.au/animancer/api/Animancer.Examples.Events/Golfer /// [AddComponentMenu(Strings.ExamplesMenuPrefix + "Golf Events - Golfer")] [HelpURL(Strings.DocsURLs.ExampleAPIDocumentation + nameof(Events) + "/" + nameof(Golfer))] public sealed class Golfer : MonoBehaviour { /************************************************************************************************************************/ private const string HitEventName = "Hit"; [SerializeField] private AnimancerComponent _Animancer; [SerializeField] private ClipTransition _Ready; [SerializeField, EventNames(HitEventName)] private ClipTransition _Swing; [SerializeField] private Rigidbody _Ball; [SerializeField] private Vector3 _HitVelocity = new Vector3(0, 10, 10); [SerializeField, Meters] private float _BallReturnHeight = -10; private Vector3 _BallStartPosition; /************************************************************************************************************************/ private void Awake() { _BallStartPosition = _Ball.position; _Ball.isKinematic = true; _Swing.Events.SetCallback(HitEventName, HitBall); _Swing.Events.OnEnd = EndSwing; } /************************************************************************************************************************/ private void OnEnable() { _Animancer.Play(_Ready); ResetBall(); // Awake only gets called once on startup but OnEnable is called every time the object is activated. // It doesn't matter in the Golf Events example, but the Hybrid Mini Game example reuses this script and // deactivates it while the Mini Game is not being played so we want to always enter the ready state when // the Mini Game starts. } /************************************************************************************************************************/ private void ResetBall() { _Ball.isKinematic = true; _Ball.position = _BallStartPosition; } /************************************************************************************************************************/ private void Update() { if (_Ball.isKinematic) { if (ExampleInput.LeftMouseDown) { _Animancer.Play(_Swing); } } else if (_Ball.position.y < _BallReturnHeight) { ResetBall(); } } /************************************************************************************************************************/ private void HitBall() { _Ball.isKinematic = false; _Ball.velocity = _HitVelocity; } /************************************************************************************************************************/ private void EndSwing() { // Since the swing animation is ending early, we want it to calculate the fade duration to fade out over // the remainder of that animation instead of just using the value specified by the _Ready transition. var fadeDuration = AnimancerEvent.GetFadeOutDuration(); _Animancer.Play(_Ready, fadeDuration); } /************************************************************************************************************************/ } }