unity之 PlayableGraph 动画应用(三)完结篇

总述:

以往的Animator, 角色需要的动画会一次性全部拖拽到列表里,加载就需要一次性的全部加载进去,造成卡顿。而AnimationClipPlayable可以按需加载 需要再加载 超时卸载,可以减少内存的占用。

角色动画特别多,常用的动画 默认加载,非常用的动画可以动态加载,设置过期时间 超时卸载。

话不多说,直接上代码:

 1 using System.Collections.Generic;
 2 using UnityEngine;
 3 using UnityEngine.Animations;
 4 using UnityEngine.Playables;
 5 
 6 public class TestPlayable : MonoBehaviour
 7 {
 8     private Animator m_Animator;
 9     //画布
10     private PlayableGraph m_PlayableGraph;
11     //输出
12     private AnimationPlayableOutput m_AnimationPlayableOutput;
13     //动画融合
14     private AnimationMixerPlayable m_AnimationMixerPlayable;
15     //动画剪辑Playable列表
16     private List<AnimationClipPlayable> m_ClipPlayableList = new List<AnimationClipPlayable>(100);
17     [SerializeField]
18     private AnimationClip[] m_Clips;
19 
20     private void Awake()
21     {
22         m_Animator = GetComponent<Animator>();
23         //创建画布
24         m_PlayableGraph = PlayableGraph.Create("testGraph");
25         //创建输出
26         m_AnimationPlayableOutput = AnimationPlayableOutput.Create(m_PlayableGraph, "OutPut", m_Animator);
27     }
28 
29     private void Start()
30     {
31         CreateMixerPlayable();
32     }
33 
34     private void CreateMixerPlayable()
35     {
36         //动画融合 有多少个动画剪辑就需要多少个动画融合
37         m_AnimationMixerPlayable = AnimationMixerPlayable.Create(m_PlayableGraph, 100);
38         //设置输出源
39         m_AnimationPlayableOutput.SetSourcePlayable(m_AnimationMixerPlayable, 0);
40     }
41 
42     private void Update()
43     {
44         if (Input.GetKeyUp(KeyCode.A))
45         {
46             if (m_ClipPlayableList.Count >= m_Clips.Length) return;
47             AnimationClip clip = m_Clips[m_ClipPlayableList.Count];
48             //根据clip 创建Playable动画剪辑
49             AnimationClipPlayable clipPlayable = AnimationClipPlayable.Create(m_PlayableGraph, clip);
50             //画布连接 playable混合器   而混合器与Playable动画剪辑相连接
51             m_PlayableGraph.Connect(clipPlayable, 0, m_AnimationMixerPlayable, m_ClipPlayableList.Count);
52             //把所有的playable动画剪辑 权重设置0
53             m_AnimationMixerPlayable.SetInputWeight(m_ClipPlayableList.Count, 0);
54             m_ClipPlayableList.Add(clipPlayable);
55         }
56         else if (Input.GetKeyUp(KeyCode.D))
57         {
58             if (m_ClipPlayableList.Count > 0)
59             {
60                 AnimationClipPlayable clipPlayable = m_ClipPlayableList[m_ClipPlayableList.Count - 1];
61                 m_ClipPlayableList.Remove(clipPlayable);
62                 clipPlayable.Destroy();
63             }
64         }
65         else if (Input.GetKeyUp(KeyCode.P))
66         {
67             Play();
68         }
69     }
70 
71     private int index = 0;
72     private void Play()
73     {
74         int count = m_ClipPlayableList.Count;
75         if (count <= 0) return;
76         if (index >= count) index = 0;
77         m_PlayableGraph.Play();
78         //通过索引获取playable
79         if (index >= m_AnimationMixerPlayable.GetInputCount()) return;
80         Playable playable = m_AnimationMixerPlayable.GetInput(index);
81         if (playable.IsNull()) return;
82         playable.SetTime(0);
83         playable.Play();
84         for (int i = 0; i < count; i++)
85         {
86             if (i == index)
87             {
88                 //需要播放的权重设置为1
89                 m_AnimationMixerPlayable.SetInputWeight(i, 1);
90             }
91             else
92             {
93                 //不播放的权重设置为0
94                 m_AnimationMixerPlayable.SetInputWeight(i, 0);
95             }
96         }
97         index++;
98     }
99 }

按 A键 添加动画剪辑,按 D键 销毁动画剪辑、按P键播放 !效果如下:

 

 好了,以上就是PlayableGraph 动画应用,对以往的动画控制器 AnimatorController 连线 + tag标识  要简单易用的多,还带来内存性能上的优化~

 

posted @ 2022-04-23 13:44  赵不灰  阅读(830)  评论(0编辑  收藏  举报