Мои Уведомления
Привет, !
Мой Аккаунт Мои Финансы Мои Подписки Мои Настройки Выход
Руководство API скрипты

Playables Примеры

Визуализатор PlayableGraph

Все примеры в этом документе используют визуализатор PlayableGraph (на фото ниже) для иллюстрации деревьев и узлов, созданных с помощью Playables API, который позволяет создавать инструменты, эффекты или другие игровые механизмы путем организации и оценки источников данных в древовидной структуре, известной как PlayableGraph. Подробнее
См. в Словарь
API. График PlayableAPI для управления Playables. Playable Graphs позволяют создавать, подключать и уничтожать игровые объекты. Подробнее
См. в Словарь
Visualizer – это инструмент, доступный через GitHub.

Чтобы использовать визуализатор PlayableGraph:

  1. Загрузите визуализатор PlayableGraph, соответствующий вашей версии Unity, из репозитория GitHub.
  2. Откройте инструмент, выбрав Окно > Визуализатор PlayableGraph.
  3. Зарегистрируйте свой график с помощью GraphVisualizerClient.Show(график PlayableGraph, имя строки).
Окно GraphVisualizer
Окно GraphVisualizer

Игровые объекты на графике представлены цветными узлами. Интенсивность цвета проволоки указывает на вес смеси. См. GitHub для получения дополнительной информации об этом инструменте.

Воспроизведение одного анимационного клипа на GameObject

В этом примере демонстрируется простой PlayableGraph с одним воспроизводимым выходом, который связан с одним воспроизводимым узлом. Воспроизводимый узел воспроизводит один анимационный клипданные анимации, которые можно использовать для анимированных персонажей или простых анимаций. Это простое «единичное» движение, такое как (один конкретный пример) «Простояние», «Ходьба» или «Бег». Подробнее
См. в Словарь
(клип). AnimationClipPlayable должен обернуть анимационный клип, чтобы сделать его совместимым с Playables API.

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class PlayAnimationSample : MonoBehaviour { public AnimationClip clip; PlayableGraph playableGraph; void Start() { playableGraph = PlayableGraph.Create(); playableGraph.SetTimeUpdateMode(DirectorUpdateMode.GameTime); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); // Wrap the clip in a playable var clipPlayable = AnimationClipPlayable.Create(playableGraph, clip); // Connect the Playable to an output playableOutput.SetSourcePlayable(clipPlayable); // Plays the Graph. playableGraph.Play(); } void OnDisable() { // Destroys all Playables and PlayableOutputs created by the graph. playableGraph.Destroy(); } }
PlayableGraph, сгенерированный PlayAnimationSample
PlayableGraph, сгенерированный PlayAnimationSample

Используйте AnimationPlayableUtilities, чтобы упростить создание и воспроизведение анимационных playables, как показано в следующем примере:

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class PlayAnimationUtilitiesSample : MonoBehaviour { public AnimationClip clip; PlayableGraph playableGraph; void Start() { AnimationPlayableUtilities.PlayClip(GetComponent(), clip, out playableGraph); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }

Создание дерева наложения анимации

В этом примере показано, как использовать AnimationMixerPlayable для смешивания двух анимационных клипов. Перед смешиванием анимационных клипов их необходимо обернуть playables. Для этого AnimationClipPlayable (clipPlayable0 и clipPlayable1) обертывает каждый AnimationClip (clip0 и clip1). Метод SetInputWeight() динамически регулирует вес смешивания каждого воспроизводимого объекта.

Хотя это и не показано в этом примере, вы также можете использовать AnimationMixerPlayable для смешивания воспроизводимых микшеров и других воспроизводимых объектов.

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class MixAnimationSample : MonoBehaviour { public AnimationClip clip0; public AnimationClip clip1; public float weight; PlayableGraph playableGraph; AnimationMixerPlayable mixerPlayable; void Start() { // Creates the graph, the mixer and binds them to the Animator. playableGraph = PlayableGraph.Create(); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerPlayable); // Creates AnimationClipPlayable and connects them to the mixer. var clipPlayable0 = AnimationClipPlayable.Create(playableGraph, clip0); var clipPlayable1 = AnimationClipPlayable.Create(playableGraph, clip1); playableGraph.Connect(clipPlayable0, 0, mixerPlayable, 0); playableGraph.Connect(clipPlayable1, 0, mixerPlayable, 1); // Plays the Graph. playableGraph.Play(); } void Update() { weight = Mathf.Clamp01(weight); mixerPlayable.SetInputWeight(0, 1.0f-weight); mixerPlayable.SetInputWeight(1, weight); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }
PlayableGraph, сгенерированный MixAnimationSample
PlayableGraph, сгенерированный MixAnimationSample

Смешение AnimationClip и AnimatorController

В этом примере показано, как использовать AnimationMixerPlayable для смешивания AnimationClip с AnimatorController. .

Перед смешиванием AnimationClip и AnimatorController их необходимо обернуть playables. Для этого AnimationClipPlayable (clipPlayable) заключает в себе AnimationClip (clip) и AnimatorControllerPlayable (ctrlPlayable) является оболочкой для RuntimeAnimatorController (контроллера). Метод SetInputWeight() динамически регулирует вес смешивания каждого воспроизводимого объекта.

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class RuntimeControllerSample : MonoBehaviour { public AnimationClip clip; public RuntimeAnimatorController controller; public float weight; PlayableGraph playableGraph; AnimationMixerPlayable mixerPlayable; void Start() { // Creates the graph, the mixer and binds them to the Animator. playableGraph = PlayableGraph.Create(); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerPlayable); // Creates AnimationClipPlayable and connects them to the mixer. var clipPlayable = AnimationClipPlayable.Create(playableGraph, clip); var ctrlPlayable = AnimatorControllerPlayable.Create(playableGraph, controller); playableGraph.Connect(clipPlayable, 0, mixerPlayable, 0); playableGraph.Connect(ctrlPlayable, 0, mixerPlayable, 1); // Plays the Graph. playableGraph.Play(); } void Update() { weight = Mathf.Clamp01(weight); mixerPlayable.SetInputWeight(0, 1.0f-weight); mixerPlayable.SetInputWeight(1, weight); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }

Создание PlayableGraph с несколькими выходами

В этом примере показано, как создать PlayableGraph с двумя разными типами воспроизводимого вывода: AudioPlayableOutput и AnimationPlayableOutput. PlayableGraph может иметь множество воспроизводимых выходных данных различных типов.

В этом примере также показано, как воспроизводить AudioClip через AudioClipPlayable, подключенный к AudioPlayableOutput.

using UnityEngine; using UnityEngine.Animations; using UnityEngine.Audio; using UnityEngine.Playables; [RequireComponent(typeof(Animator))] [RequireComponent(typeof(AudioSource))] public class MultiOutputSample : MonoBehaviour { public AnimationClip animationClip; public AudioClip audioClip; PlayableGraph playableGraph; void Start() { playableGraph = PlayableGraph.Create(); // Create the outputs. var animationOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); var audioOutput = AudioPlayableOutput.Create(playableGraph, "Audio", GetComponent()); // Create the playables. var animationClipPlayable = AnimationClipPlayable.Create(playableGraph, animationClip); var audioClipPlayable = AudioClipPlayable.Create(playableGraph, audioClip, true); // Connect the playables to an output animationOutput.SetSourcePlayable(animationClipPlayable); audioOutput.SetSourcePlayable(audioClipPlayable); // Plays the Graph. playableGraph.Play(); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }
PlayableGraph, сгенерированный MultiOutputSample
PlayableGraph, сгенерированный MultiOutputSample

Управление состоянием воспроизведения дерева

В этом примере показано, как использовать метод Playable.SetPlayState() для управления состоянием воспроизведения узла в PlayableGraph. дерево. Метод SetPlayState управляет состоянием воспроизведения всего дерева, одной из его ветвей или отдельного узла.

При установке состояния воспроизведения узла это состояние распространяется на все его дочерние элементы, независимо от их состояний воспроизведения. Например, если дочерний узел явно приостановлен, установка родительского узла в состояние «воспроизводится» также устанавливает для всех его дочерних узлов состояние «воспроизведение».

В этом примере PlayableGraph содержит микшер, который смешивает два анимационных клипа. AnimationClipPlayable оборачивает каждый анимационный клип, а метод SetPlayState() явно приостанавливает второй воспроизводимый объект. Второй AnimationClipPlayable явно приостановлен, поэтому его внутреннее время не увеличивается и выводит то же значение. Точное значение зависит от конкретного времени, когда AnimationClipPlayable был приостановлен.

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class PauseSubGraphAnimationSample : MonoBehaviour { public AnimationClip clip0; public AnimationClip clip1; PlayableGraph playableGraph; AnimationMixerPlayable mixerPlayable; void Start() { // Creates the graph, the mixer and binds them to the Animator. playableGraph = PlayableGraph.Create(); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); mixerPlayable = AnimationMixerPlayable.Create(playableGraph, 2); playableOutput.SetSourcePlayable(mixerPlayable); // Creates AnimationClipPlayable and connects them to the mixer. var clipPlayable0 = AnimationClipPlayable.Create(playableGraph, clip0); var clipPlayable1 = AnimationClipPlayable.Create(playableGraph, clip1); playableGraph.Connect(clipPlayable0, 0, mixerPlayable, 0); playableGraph.Connect(clipPlayable1, 0, mixerPlayable, 1); mixerPlayable.SetInputWeight(0, 1.0f); mixerPlayable.SetInputWeight(1, 1.0f); clipPlayable1.SetPlayState(PlayState.Paused); // Plays the Graph. playableGraph.Play(); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }
PlayableGraph, созданный PauseSubGraphAnimationSample. Обратите внимание, что второй клип поставлен на паузу (красный край).
PlayableGraph, созданный PauseSubGraphAnimationSample. Обратите внимание, что второй клип поставлен на паузу (красный край).

Управление временем дерева

В этом примере показано, как использовать метод Play() для воспроизведения PlayableGraph, как использовать метод SetPlayState() для приостановки воспроизводимого объекта и как использовать метод SetTime() для ручной установки локального времени воспроизводимого объекта. с переменной.

using UnityEngine; using UnityEngine.Playables; using UnityEngine.Animations; [RequireComponent(typeof(Animator))] public class PlayWithTimeControlSample : MonoBehaviour { public AnimationClip clip; public float time; PlayableGraph playableGraph; AnimationClipPlayable playableClip; void Start() { playableGraph = PlayableGraph.Create(); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); // Wrap the clip in a playable playableClip = AnimationClipPlayable.Create(playableGraph, clip); // Connect the Playable to an output playableOutput.SetSourcePlayable(playableClip); // Plays the Graph. playableGraph.Play(); // Stops time from progressing automatically. playableClip.SetPlayState(PlayState.Paused); } void Update () { // Control the time manually playableClip.SetTime(time); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }

Создание игрового поведения

В этом примере показано, как создавать собственные игровые объекты с помощью открытого класса PlayableBehaviour. В этом примере также показано, как переопределить виртуальный метод PrepareFrame() для управления узлами в PlayableGraph. Пользовательские playables могут переопределять любые другие виртуальные методы класса PlayableBehaviour.

В этом примере управляемые узлы представляют собой серию анимационных клипов (clipsToPlay). SetInputMethod() изменяет вес наложения каждого анимационного клипа, обеспечивая одновременное воспроизведение только одного клипа, а SetTime() настраивает местное время таким образом, чтобы воспроизведение начиналось в момент активации анимационного клипа.

using UnityEngine; using UnityEngine.Animations; using UnityEngine.Playables; public class PlayQueuePlayable : PlayableBehaviour { private int m_CurrentClipIndex = -1; private float m_TimeToNextClip; private Playable mixer; public void Initialize(AnimationClip[] clipsToPlay, Playable owner, PlayableGraph graph) { owner.SetInputCount(1); mixer = AnimationMixerPlayable.Create(graph, clipsToPlay.Length); graph.Connect(mixer, 0, owner, 0); owner.SetInputWeight(0, 1); for (int clipIndex = 0 ; clipIndex < mixer.GetInputCount() ; ++clipIndex) { graph.Connect(AnimationClipPlayable.Create(graph, clipsToPlay[clipIndex]), 0, mixer, clipIndex); mixer.SetInputWeight(clipIndex, 1.0f); } } override public void PrepareFrame(Playable owner, FrameData info) { if (mixer.GetInputCount() == 0) return; // Advance to next clip if necessary m_TimeToNextClip -= (float)info.deltaTime; if (m_TimeToNextClip <= 0.0f) { m_CurrentClipIndex++; if (m_CurrentClipIndex >= mixer.GetInputCount()) m_CurrentClipIndex = 0; var currentClip = (AnimationClipPlayable)mixer.GetInput(m_CurrentClipIndex); // Reset the time so that the next clip starts at the correct position currentClip.SetTime(0); m_TimeToNextClip = currentClip.GetAnimationClip().length; } // Adjust the weight of the inputs for (int clipIndex = 0 ; clipIndex < mixer.GetInputCount(); ++clipIndex) { if (clipIndex == m_CurrentClipIndex) mixer.SetInputWeight(clipIndex, 1.0f); else mixer.SetInputWeight(clipIndex, 0.0f); } } } [RequireComponent(typeof (Animator))] public class PlayQueueSample : MonoBehaviour { public AnimationClip[] clipsToPlay; PlayableGraph playableGraph; void Start() { playableGraph = PlayableGraph.Create(); var playQueuePlayable = ScriptPlayable.Create(playableGraph); var playQueue = playQueuePlayable.GetBehaviour(); playQueue.Initialize(clipsToPlay, playQueuePlayable, playableGraph); var playableOutput = AnimationPlayableOutput.Create(playableGraph, "Animation", GetComponent()); playableOutput.SetSourcePlayable(playQueuePlayable); playableOutput.SetSourceInputPort(0); playableGraph.Play(); } void OnDisable() { // Destroys all Playables and Outputs created by the graph. playableGraph.Destroy(); } }
PlayableGraph, сгенерированный PlayQueueSample
PlayableGraph, сгенерированный PlayQueueSample
Вы можете отблагодарить автора, за перевод документации на русский язык. ₽ Спасибо
Руководство Unity 2021.3