关闭

Unity 编辑器下控制播放Animator

标签: unity编辑器人物
28653人阅读 评论(4) 收藏 举报
分类:

     在Unity编辑器的Scene视图进行控制播放Animator,可以借助方法StartPlayback、StopPlayback、StartRecording和StopRecording,具体可以参照以下例子:


创建一个带Controller的Animator对象,可以看到此时人物呈现T型姿势。附上新脚本EditAnimator,此为空脚本,如下:
 C# Code 
1
2
3
4
5
6
using UnityEngine;

public class EditAnimator : MonoBehaviour 
{
}
创建一个这个脚本的编辑器类EditAnimatorInspector,代码如下:
 C# Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
using UnityEditor;
using UnityEngine;

[CustomEditor(typeof(EditAnimator))]
public class EditAnimatorInspector : Editor
{
    /// <summary>
    /// 滑动杆的当前时间
    /// </summary>
    private float m_CurTime;
    
    /// <summary>
    /// 是否已经烘培过
    /// </summary>
    private bool m_HasBake;
    
    /// <summary>
    /// 当前是否是预览播放状态
    /// </summary>
    private bool m_Playing;

    /// <summary>
    /// 当前运行时间
    /// </summary>
    private float m_RunningTime;
    
    /// <summary>
    /// 上一次系统时间
    /// </summary>
    private double m_PreviousTime;
    
    /// <summary>
    /// 总的记录时间
    /// </summary>
    private float m_RecorderStopTime;

    /// <summary>
    /// 滑动杆总长度
    /// </summary>
    private const float kDuration = 30f;

    private Animator m_Animator;

    private EditAnimator editAnimator { get { return target as EditAnimator; } }

    private Animator animator
    {
        get { return m_Animator ?? (m_Animator = editAnimator.GetComponent<Animator>()); }
    }

    void OnEnable()
    {
        m_PreviousTime = EditorApplication.timeSinceStartup;
        EditorApplication.update += inspectorUpdate;
    }

    void OnDisable()
    {
        EditorApplication.update -= inspectorUpdate;
    }

    public override void OnInspectorGUI()
    {
        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Bake"))
        {
            m_HasBake = false;
            bake();
        }
        if (GUILayout.Button("Play"))
        {
            play();
        }
        if (GUILayout.Button("Stop"))
        {
            stop();
        }
        EditorGUILayout.EndHorizontal();
        m_CurTime = EditorGUILayout.Slider("Time:", m_CurTime, 0f, kDuration);
        manualUpdate();
    }

    /// <summary>
    /// 烘培记录动画数据
    /// </summary>
    private void bake()
    {
        if (m_HasBake)
        {
            return;
        }

        if (Application.isPlaying || animator == null)
        {
            return;
        }

        const float frameRate = 30f;
        const int frameCount = (int)((kDuration * frameRate) + 2);
        animator.Rebind();
        animator.StopPlayback();
        animator.recorderStartTime = 0;

        // 开始记录指定的帧数
        animator.StartRecording(frameCount);

        for (var i = 0; i < frameCount - 1; i++)
        {
            // 这里可以在指定的时间触发新的动画状态
            if (i == 200)
            {
                animator.SetTrigger("Dance");
            }

            // 记录每一帧
            animator.Update(1.0f / frameRate);
        }
        // 完成记录
        animator.StopRecording();

        // 开启回放模式
        animator.StartPlayback();
        m_HasBake = true;
        m_RecorderStopTime = animator.recorderStopTime;
    }

    /// <summary>
    /// 进行预览播放
    /// </summary>
    private void play()
    {
        if (Application.isPlaying || animator == null)
        {
            return;
        }

        bake();
        m_RunningTime = 0f;
        m_Playing = true;
    }

    /// <summary>
    /// 停止预览播放
    /// </summary>
    private void stop()
    {
        if (Application.isPlaying || animator == null)
        {
            return;
        }

        m_Playing = false;
        m_CurTime = 0f;
    }

    /// <summary>
    /// 预览播放状态下的更新
    /// </summary>
    private void update()
    {
        if (Application.isPlaying || animator == null)
        {
            return;
        }

        if (m_RunningTime > m_RecorderStopTime)
        {
            m_Playing = false;
            return;
        }

        // 设置回放的时间位置
        animator.playbackTime = m_RunningTime;
        animator.Update(0);
        m_CurTime = m_RunningTime;
    }

    /// <summary>
    /// 非预览播放状态下,通过滑杆来播放当前动画帧
    /// </summary>
    private void manualUpdate()
    {
        if (animator && !m_Playing && m_HasBake && m_CurTime < m_RecorderStopTime)
        {
            animator.playbackTime = m_CurTime;
            animator.Update(0);
        }
    }

    private void inspectorUpdate()
    {
        var delta = EditorApplication.timeSinceStartup - m_PreviousTime;
        m_PreviousTime = EditorApplication.timeSinceStartup;

        if (!Application.isPlaying && m_Playing)
        {
            m_RunningTime = Mathf.Clamp(m_RunningTime + (float)delta, 0f, kDuration);
            update();
        }
    }
}
检视器效果如下:

点击"Bake",可以看到此时人物姿势变成了动画状态的第一帧,如下所示:

拖动滑杆,即可播放当前时间的那一帧,如下所示:

点击"Play",即可以自动播放整个动画,如下所示:

1
0
查看评论

Unity动画知识之二:Animator动画状态机

文/拉撒路   上次我们讲过Unity游戏动画从入门到住院,今天我们来讲一下动画状态机。   好了,现在我们已经成功的导入了动画。接下来要玩的东西就很装13啦。因为大部分动画师是用不到这家伙的,需要掌握这个技能的,至少也是动画组长级别了。嗯。。。一个组只有你一个动画的,闭嘴!给你个同情的...
  • qq_34134078
  • qq_34134078
  • 2016-11-09 00:56
  • 5374

Mecanim Animator使用详解

1. 简介     Mecanim把游戏中的角色设计提高到了一个新的层次,使用Mecanim可以通过Retargeting(重定向)来提高角色动画的重用性。在处理人类角色动画时,用户可以使用动画状态机来处理动画之间的过渡及动画之间的逻辑。  2. Animat...
  • MyArrow
  • MyArrow
  • 2015-04-24 10:15
  • 37178

unity 新的动画系统 Animator的使用(原)

Animator是unity新的动画系统,除了基本的播放动画功能之外,还提供了更强大的其它功能 基本篇 1新建AnimatorController,将动作拖到AnimatorController,将动作做连线,新建状态值,设置连线通过条件的状态值 2代码使用SetInteger("变量名...
  • u014635337
  • u014635337
  • 2015-07-17 00:34
  • 12017

Unity3D Animator不常用方法

原创文章如需转载请注明:转载自 脱莫柔Unity3D学习之旅 QQ群:【Unity3D(AR/VR) 334163814】【Unity3D(游戏) 119706192】 本文链接地址: Animator不常用方法 回到起始帧 public void animToStar...
  • asd237241291
  • asd237241291
  • 2014-12-11 12:15
  • 16817

Animator的基本用法

这里仅仅介绍Animator的一些基本的用法: 说到Animator,最重要的最常用的的就是ObjectAnimator类,因为这个类可以对任意View的任意属性进行操作。 首先以ImageView为例,以下所有的操作都针对ImageView: 1.只展示一种动画效果(只改变控件对象的一个属性),代...
  • zhaozhiwen6140
  • zhaozhiwen6140
  • 2016-07-25 20:34
  • 1208

uinity Animator 和Animation的正播,捯播,暂停动画实现方法(测试)

首先要获得AnimationClip 对象, 点出来speed,当speed = 1.0f 正播动画,speed = -1的时候捯播动画,捯播的时候要先把normalizedTime  = 1.0f; 暂停只要使speed = 0; using UnityEngine; using...
  • lilybeast
  • lilybeast
  • 2014-02-21 16:45
  • 2173

Animator动画的录制与回播源码

  • 2017-12-19 17:48
  • 2KB
  • 下载

安卓动画开始,暂停和停止

android 在3.0之前经常使用的tween animation在网上已经有人实现了动画的暂停效果,但是对于property animation的暂停尚未实现,由于项目需要,我将属性动画的暂停、停止、播放的三个操作整理如下 对于视图和属性动画的实例化和事件,请直接看代码 暂停anim...
  • csdngemming
  • csdngemming
  • 2016-01-13 12:26
  • 7090

Unity中的trigger

前言最近在一家公司实习,公司用unity做项目,所以开始抛弃cocos,步入unity的深坑,笔主在研究unity时,发现网上很少有人会去分析引擎内部的实现,更加偏向于“是什么”而不是“为什么”,笔主接下来的一段时间可能都会写一些关于unity的个人理解,由于看不到源码,笔主只能通过类比cocos和...
  • qq_22984991
  • qq_22984991
  • 2016-12-26 14:27
  • 979

【Unity】技巧集合

转发,请保持地址:http://blog.csdn.net/stalendp/article/details/17114135 这篇文章将收集unity的相关技巧,会不断地更新内容。 1)保存运行中的状态 unity在运行状态时是不能够保存的。但在运行时编辑的时候,有时会发现比较好的效果想保存。这...
  • stalendp
  • stalendp
  • 2013-12-04 10:27
  • 31206
    个人资料
    • 访问:3555420次
    • 积分:36075
    • 等级:
    • 排名:第137名
    • 原创:402篇
    • 转载:88篇
    • 译文:5篇
    • 评论:3425条
    个人说明
    联系方式:
    文章存档
    最新评论