激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - C# - Unity代碼實現(xiàn)序列幀動畫播放器

Unity代碼實現(xiàn)序列幀動畫播放器

2022-03-10 14:17serenahaven C#

這篇文章主要為大家詳細介紹了Unity代碼實現(xiàn)序列幀動畫播放器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

序列幀動畫經(jīng)常用到,最直接的方式就是用Animation錄制。但某些情況下這種方式并不是太友好,需要靠代碼的方式進行序列幀動畫的實現(xiàn)。

代碼實現(xiàn)序列幀動畫,基本的思路是定義一個序列幀的數(shù)組/列表,根據(jù)時間的流逝來確定使用哪一幀并更新顯示。

NGUI的UI2DSpriteAnimation已經(jīng)實現(xiàn)了此功能,但是它支持的目標(biāo)只有Native2D的SpriteRenderer組件或者NGUI自身的UI2DSprite組件,并不支持UGUI的Image組件。

當(dāng)然可以通過改寫源碼的方式來添加對Image組件的支持,不過秉著學(xué)習(xí)的目的,我這里重新寫了一個同時支持Image組件和SpriteRenderer組件的序列幀動畫播放器。

代碼如下,注釋寫的很詳細了,不再贅述。

?
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
using UnityEngine;
using UnityEngine.UI;
using System;
 
/// <summary>
/// 序列幀動畫播放器
/// 支持UGUI的Image和Unity2D的SpriteRenderer
/// </summary>
public class FrameAnimator : MonoBehaviour
{
 /// <summary>
 /// 序列幀
 /// </summary>
 public Sprite[] Frames{ get { return frames; } set { frames = value; } }
 
 [SerializeField]private Sprite[] frames = null;
 
 /// <summary>
 /// 幀率,為正時正向播放,為負時反向播放
 /// </summary>
 public float Framerate { get { return framerate; } set { framerate = value; } }
 
 [SerializeField] private float framerate = 20.0f;
 
 /// <summary>
 /// 是否忽略timeScale
 /// </summary>
 public bool IgnoreTimeScale{ get { return ignoreTimeScale; } set { ignoreTimeScale = value; } }
 
 [SerializeField]private bool ignoreTimeScale = true;
 
 /// <summary>
 /// 是否循環(huán)
 /// </summary>
 public bool Loop{ get { return loop; } set { loop = value; } }
 
 [SerializeField]private bool loop = true;
 
 //動畫曲線
 [SerializeField]private AnimationCurve curve = new AnimationCurve (new Keyframe (0, 1, 0, 0), new Keyframe (1, 1, 0, 0));
 
 /// <summary>
 /// 結(jié)束事件
 /// 在每次播放完一個周期時觸發(fā)
 /// 在循環(huán)模式下觸發(fā)此事件時,當(dāng)前幀不一定為結(jié)束幀
 /// </summary>
 public event Action FinishEvent;
 
 //目標(biāo)Image組件
 private Image image;
 //目標(biāo)SpriteRenderer組件
 private SpriteRenderer spriteRenderer;
 //當(dāng)前幀索引
 private int currentFrameIndex = 0;
 //下一次更新時間
 private float timer = 0.0f;
 //當(dāng)前幀率,通過曲線計算而來
 private float currentFramerate = 20.0f;
 
 /// <summary>
 /// 重設(shè)動畫
 /// </summary>
 public void Reset ()
 {
 currentFrameIndex = framerate < 0 ? frames.Length - 1 : 0;
 }
 
 /// <summary>
 /// 從停止的位置播放動畫
 /// </summary>
 public void Play ()
 {
 this.enabled = true;
 }
 
 /// <summary>
 /// 暫停動畫
 /// </summary>
 public void Pause ()
 {
 this.enabled = false;
 }
 
 /// <summary>
 /// 停止動畫,將位置設(shè)為初始位置
 /// </summary>
 public void Stop ()
 {
 Pause ();
 Reset ();
 }
 
 //自動開啟動畫
 void Start ()
 {
 image = this.GetComponent<Image> ();
 spriteRenderer = this.GetComponent<SpriteRenderer> ();
 #if UNITY_EDITOR
 if (image == null && spriteRenderer == null) {
 Debug.LogWarning ("No available component found. 'Image' or 'SpriteRenderer' required.", this.gameObject);
 }
 #endif
 }
 
 void Update ()
 {
 //幀數(shù)據(jù)無效,禁用腳本
 if (frames == null || frames.Length == 0) {
 this.enabled = false;
 } else {
 //從曲線值計算當(dāng)前幀率
 float curveValue = curve.Evaluate ((float)currentFrameIndex / frames.Length);
 float curvedFramerate = curveValue * framerate;
 //幀率有效
 if (curvedFramerate != 0) {
 //獲取當(dāng)前時間
 float time = ignoreTimeScale ? Time.unscaledTime : Time.time;
 //計算幀間隔時間
 float interval = Mathf.Abs (1.0f / curvedFramerate);
 //滿足更新條件,執(zhí)行更新操作
 if (time - timer > interval) {
 //執(zhí)行更新操作
 DoUpdate ();
 }
 }
 #if UNITY_EDITOR
 else {
 Debug.LogWarning ("Framerate got '0' value, animation stopped.");
 }
 #endif
 }
 }
 
 //具體更新操作
 private void DoUpdate ()
 {
 //計算新的索引
 int nextIndex = currentFrameIndex + (int)Mathf.Sign (currentFramerate);
 //索引越界,表示已經(jīng)到結(jié)束幀
 if (nextIndex < 0 || nextIndex >= frames.Length) {
 //廣播事件
 if (FinishEvent != null) {
 FinishEvent ();
 }
 //非循環(huán)模式,禁用腳本
 if (loop == false) {
 currentFrameIndex = Mathf.Clamp (currentFrameIndex, 0, frames.Length - 1);
 this.enabled = false;
 return;
 }
 }
 //鉗制索引
 currentFrameIndex = nextIndex % frames.Length;
 //更新圖片
 if (image != null) {
 image.sprite = frames [currentFrameIndex];
 } else if (spriteRenderer != null) {
 spriteRenderer.sprite = frames [currentFrameIndex];
 }
 //設(shè)置計時器為當(dāng)前時間
 timer = ignoreTimeScale ? Time.unscaledTime : Time.time;
 }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/SerenaHaven/article/details/79273114

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久草在线最新免费 | 亚洲资源在线 | 久久网综合 | 羞羞视频在线免费 | 久久男人的天堂 | 欧美精品激情视频 | 毛片午夜| 国产精品99久久久久久久女警 | 无码av女优 | 国产乱色精品成人免费视频 | 久草在线最新 | 欧美精品一区二区三区久久久 | 欧美日韩精品一区二区三区在线观看 | 曰韩一二三区 | 黄网站色成年大片免费高 | 久草手机在线视频 | 亚洲午夜1000理论片aa | 日本在线视频二区 | 九一成人| 成人免费看视频 | 91高清视频在线免费观看 | av在线免费播放 | 最新在线黄色网址 | 国产欧美日韩一区二区三区四区 | 日韩高清影视 | 久久99精品久久久久久秒播放器 | 亚洲一区 国产精品 | 久久久久久久一区二区三区 | 色偷偷一区 | 午夜视频免费播放 | 久久久久久久91 | 88xx成人精品视频 | 成人免费毛片网站 | av电影在线观看免费 | 99久久超碰中文字幕伊人 | 99成人精品视频 | 国产免费久久久久 | 日本高清电影在线播放 | 91精品国产91热久久久做人人 | 中文字幕电影免费播放 | 久草在线最新 |