// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik // #pragma warning disable CS0649 // Field is never assigned to, and will always have its default value. using System; using UnityEngine; namespace Animancer.Examples.FineControl { /// /// Demonstrates how to use a to play animations by name. /// /// Named Animations /// https://kybernetik.com.au/animancer/api/Animancer.Examples.FineControl/NamedAnimations /// [AddComponentMenu(Strings.ExamplesMenuPrefix + "Fine Control - Named Animations")] [HelpURL(Strings.DocsURLs.ExampleAPIDocumentation + nameof(FineControl) + "/" + nameof(NamedAnimations))] public sealed class NamedAnimations : MonoBehaviour { /************************************************************************************************************************/ [SerializeField] private NamedAnimancerComponent _Animancer; [SerializeField] private AnimationClip _Walk; [SerializeField] private AnimationClip _Run; /************************************************************************************************************************/ // Idle. /************************************************************************************************************************/ // Called by a UI Button. /// /// Plays the idle animation by name. This requires the animation to already have a state in the /// , which has already been done in this example by adding it to the /// list in the Inspector. /// /// If it has not been added, this method will simply do nothing. /// public void PlayIdle() { _Animancer.TryPlay("Humanoid-Idle"); } /************************************************************************************************************************/ // Walk. /************************************************************************************************************************/ // Called by a UI Button. /// /// Plays the walk animation by name. Unlike the idle animation, this one has not been added to the /// Inspector list so it will not exist and this method will log a warning unless you call /// first. /// public void PlayWalk() { var state = _Animancer.TryPlay("Humanoid-Walk"); if (state == null) Debug.LogWarning("No state has been registered with 'Humanoid-Walk' as its key yet."); // _Animancer.TryPlay(_Walk.name); would also work, // but if we are going to use the clip we should really just use _Animancer.Play(_Walk); // The whole point is to play animations by name in situations where you don't have the clip. } /************************************************************************************************************************/ // Called by a UI Button. /// /// Creates a state for the walk animation so that can play it. /// /// /// Calling this method more than once will throw an because a state already /// exists with the key it's trying to use (the animation's name). /// /// If we wanted to allow repeated calls we could use /// instead, which would create a state the /// first time then return the same one every time after that. /// /// If we wanted to actually create multiple states for the same animation, we would have to use the optional /// `key` parameter to specify a different key for each of them. /// public void InitializeWalkState() { _Animancer.States.Create(_Walk); Debug.Log("Created a state to play " + _Walk, this); } /************************************************************************************************************************/ // Run. /************************************************************************************************************************/ // Called by a UI Button. /// /// Plays the run animation using a direct reference to show that the ability to play animations by /// name in a does not prevent it from also using direct references like /// the base . /// public void PlayRun() { _Animancer.Play(_Run); // What actually happens internally looks more like this: // object key = _Animancer.GetKey(_Run); // var state = _Animancer.GetOrCreate(key, _Run); // _Animancer.Play(state); // The base AnimancerComponent.GetKey returns the AnimationClip to use as its own key, but // NamedAnimancerComponent overrides it to instead return the clip's name. This is a bit less // efficient, but it allows us to use clips or names interchangeably. // After the 'Run' state has been created, we could do any of the following: // _Animancer.States[_Run] or _Animancer.States["Run"]. // _Animancer.Play(_Run) or _Animancer.TryPlay("Run"). } /************************************************************************************************************************/ } }