415 lines
11 KiB
C#
415 lines
11 KiB
C#
|
using UnityEngine;
|
|||
|
|
|||
|
namespace FairyGUI
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public class MovieClip : Image
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public class Frame
|
|||
|
{
|
|||
|
public NTexture texture;
|
|||
|
public float addDelay;
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public float interval;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public bool swing;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public float repeatDelay;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public float timeScale;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Whether to ignore Unity time scale.
|
|||
|
/// </summary>
|
|||
|
public bool ignoreEngineTimeScale;
|
|||
|
|
|||
|
Frame[] _frames;
|
|||
|
int _frameCount;
|
|||
|
int _frame;
|
|||
|
bool _playing;
|
|||
|
int _start;
|
|||
|
int _end;
|
|||
|
int _times;
|
|||
|
int _endAt;
|
|||
|
int _status; //0-none, 1-next loop, 2-ending, 3-ended
|
|||
|
|
|||
|
float _frameElapsed; //当前帧延迟
|
|||
|
bool _reversed;
|
|||
|
int _repeatedCount;
|
|||
|
TimerCallback _timerDelegate;
|
|||
|
|
|||
|
EventListener _onPlayEnd;
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public MovieClip()
|
|||
|
{
|
|||
|
interval = 0.1f;
|
|||
|
_playing = true;
|
|||
|
_timerDelegate = OnTimer;
|
|||
|
timeScale = 1;
|
|||
|
ignoreEngineTimeScale = false;
|
|||
|
|
|||
|
if (Application.isPlaying)
|
|||
|
{
|
|||
|
onAddedToStage.Add(OnAddedToStage);
|
|||
|
onRemovedFromStage.Add(OnRemoveFromStage);
|
|||
|
}
|
|||
|
|
|||
|
SetPlaySettings();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public EventListener onPlayEnd
|
|||
|
{
|
|||
|
get { return _onPlayEnd ?? (_onPlayEnd = new EventListener(this, "onPlayEnd")); }
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public Frame[] frames
|
|||
|
{
|
|||
|
get
|
|||
|
{
|
|||
|
return _frames;
|
|||
|
}
|
|||
|
set
|
|||
|
{
|
|||
|
_frames = value;
|
|||
|
_scale9Grid = null;
|
|||
|
_scaleByTile = false;
|
|||
|
|
|||
|
if (_frames == null)
|
|||
|
{
|
|||
|
_frameCount = 0;
|
|||
|
graphics.texture = null;
|
|||
|
CheckTimer();
|
|||
|
return;
|
|||
|
}
|
|||
|
_frameCount = frames.Length;
|
|||
|
|
|||
|
if (_end == -1 || _end > _frameCount - 1)
|
|||
|
_end = _frameCount - 1;
|
|||
|
if (_endAt == -1 || _endAt > _frameCount - 1)
|
|||
|
_endAt = _frameCount - 1;
|
|||
|
|
|||
|
if (_frame < 0 || _frame > _frameCount - 1)
|
|||
|
_frame = _frameCount - 1;
|
|||
|
|
|||
|
InvalidateBatchingState();
|
|||
|
|
|||
|
_frameElapsed = 0;
|
|||
|
_repeatedCount = 0;
|
|||
|
_reversed = false;
|
|||
|
|
|||
|
DrawFrame();
|
|||
|
CheckTimer();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public bool playing
|
|||
|
{
|
|||
|
get { return _playing; }
|
|||
|
set
|
|||
|
{
|
|||
|
if (_playing != value)
|
|||
|
{
|
|||
|
_playing = value;
|
|||
|
CheckTimer();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public int frame
|
|||
|
{
|
|||
|
get { return _frame; }
|
|||
|
set
|
|||
|
{
|
|||
|
if (_frame != value)
|
|||
|
{
|
|||
|
if (_frames != null && value >= _frameCount)
|
|||
|
value = _frameCount - 1;
|
|||
|
|
|||
|
_frame = value;
|
|||
|
_frameElapsed = 0;
|
|||
|
DrawFrame();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public void Rewind()
|
|||
|
{
|
|||
|
_frame = 0;
|
|||
|
_frameElapsed = 0;
|
|||
|
_reversed = false;
|
|||
|
_repeatedCount = 0;
|
|||
|
DrawFrame();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="anotherMc"></param>
|
|||
|
public void SyncStatus(MovieClip anotherMc)
|
|||
|
{
|
|||
|
_frame = anotherMc._frame;
|
|||
|
_frameElapsed = anotherMc._frameElapsed;
|
|||
|
_reversed = anotherMc._reversed;
|
|||
|
_repeatedCount = anotherMc._repeatedCount;
|
|||
|
DrawFrame();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
/// <param name="time"></param>
|
|||
|
public void Advance(float time)
|
|||
|
{
|
|||
|
int beginFrame = _frame;
|
|||
|
bool beginReversed = _reversed;
|
|||
|
float backupTime = time;
|
|||
|
while (true)
|
|||
|
{
|
|||
|
float tt = interval + _frames[_frame].addDelay;
|
|||
|
if (_frame == 0 && _repeatedCount > 0)
|
|||
|
tt += repeatDelay;
|
|||
|
if (time < tt)
|
|||
|
{
|
|||
|
_frameElapsed = 0;
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
time -= tt;
|
|||
|
|
|||
|
if (swing)
|
|||
|
{
|
|||
|
if (_reversed)
|
|||
|
{
|
|||
|
_frame--;
|
|||
|
if (_frame <= 0)
|
|||
|
{
|
|||
|
_frame = 0;
|
|||
|
_repeatedCount++;
|
|||
|
_reversed = !_reversed;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_frame++;
|
|||
|
if (_frame > _frameCount - 1)
|
|||
|
{
|
|||
|
_frame = Mathf.Max(0, _frameCount - 2);
|
|||
|
_repeatedCount++;
|
|||
|
_reversed = !_reversed;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_frame++;
|
|||
|
if (_frame > _frameCount - 1)
|
|||
|
{
|
|||
|
_frame = 0;
|
|||
|
_repeatedCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_frame == beginFrame && _reversed == beginReversed) //走了一轮了
|
|||
|
{
|
|||
|
float roundTime = backupTime - time; //这就是一轮需要的时间
|
|||
|
time -= Mathf.FloorToInt(time / roundTime) * roundTime; //跳过
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DrawFrame();
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
///
|
|||
|
/// </summary>
|
|||
|
public void SetPlaySettings()
|
|||
|
{
|
|||
|
SetPlaySettings(0, -1, 0, -1);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 从start帧开始,播放到end帧(-1表示结尾),重复times次(0表示无限循环),循环结束后,停止在endAt帧(-1表示参数end)
|
|||
|
/// </summary>
|
|||
|
/// <param name="start"></param>
|
|||
|
/// <param name="end"></param>
|
|||
|
/// <param name="times"></param>
|
|||
|
/// <param name="endAt"></param>
|
|||
|
public void SetPlaySettings(int start, int end, int times, int endAt)
|
|||
|
{
|
|||
|
_start = start;
|
|||
|
_end = end;
|
|||
|
if (_end == -1 || _end > _frameCount - 1)
|
|||
|
_end = _frameCount - 1;
|
|||
|
_times = times;
|
|||
|
_endAt = endAt;
|
|||
|
if (_endAt == -1)
|
|||
|
_endAt = _end;
|
|||
|
_status = 0;
|
|||
|
this.frame = start;
|
|||
|
}
|
|||
|
|
|||
|
void OnAddedToStage()
|
|||
|
{
|
|||
|
if (_playing && _frameCount > 0)
|
|||
|
Timers.inst.AddUpdate(_timerDelegate);
|
|||
|
}
|
|||
|
|
|||
|
void OnRemoveFromStage()
|
|||
|
{
|
|||
|
Timers.inst.Remove(_timerDelegate);
|
|||
|
}
|
|||
|
|
|||
|
void CheckTimer()
|
|||
|
{
|
|||
|
if (!Application.isPlaying)
|
|||
|
return;
|
|||
|
|
|||
|
if (_playing && _frameCount > 0 && this.stage != null)
|
|||
|
Timers.inst.AddUpdate(_timerDelegate);
|
|||
|
else
|
|||
|
Timers.inst.Remove(_timerDelegate);
|
|||
|
}
|
|||
|
|
|||
|
void OnTimer(object param)
|
|||
|
{
|
|||
|
if (!_playing || _frameCount == 0 || _status == 3)
|
|||
|
return;
|
|||
|
|
|||
|
float dt;
|
|||
|
if (ignoreEngineTimeScale)
|
|||
|
{
|
|||
|
dt = Time.unscaledDeltaTime;
|
|||
|
if (dt > 0.1f)
|
|||
|
dt = 0.1f;
|
|||
|
}
|
|||
|
else
|
|||
|
dt = Time.deltaTime;
|
|||
|
if (timeScale != 1)
|
|||
|
dt *= timeScale;
|
|||
|
|
|||
|
_frameElapsed += dt;
|
|||
|
float tt = interval + _frames[_frame].addDelay;
|
|||
|
if (_frame == 0 && _repeatedCount > 0)
|
|||
|
tt += repeatDelay;
|
|||
|
if (_frameElapsed < tt)
|
|||
|
return;
|
|||
|
|
|||
|
_frameElapsed -= tt;
|
|||
|
if (_frameElapsed > interval)
|
|||
|
_frameElapsed = interval;
|
|||
|
|
|||
|
if (swing)
|
|||
|
{
|
|||
|
if (_reversed)
|
|||
|
{
|
|||
|
_frame--;
|
|||
|
if (_frame <= 0)
|
|||
|
{
|
|||
|
_frame = 0;
|
|||
|
_repeatedCount++;
|
|||
|
_reversed = !_reversed;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_frame++;
|
|||
|
if (_frame > _frameCount - 1)
|
|||
|
{
|
|||
|
_frame = Mathf.Max(0, _frameCount - 2);
|
|||
|
_repeatedCount++;
|
|||
|
_reversed = !_reversed;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
_frame++;
|
|||
|
if (_frame > _frameCount - 1)
|
|||
|
{
|
|||
|
_frame = 0;
|
|||
|
_repeatedCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (_status == 1) //new loop
|
|||
|
{
|
|||
|
_frame = _start;
|
|||
|
_frameElapsed = 0;
|
|||
|
_status = 0;
|
|||
|
DrawFrame();
|
|||
|
}
|
|||
|
else if (_status == 2) //ending
|
|||
|
{
|
|||
|
_frame = _endAt;
|
|||
|
_frameElapsed = 0;
|
|||
|
_status = 3; //ended
|
|||
|
DrawFrame();
|
|||
|
|
|||
|
DispatchEvent("onPlayEnd", null);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DrawFrame();
|
|||
|
if (_frame == _end)
|
|||
|
{
|
|||
|
if (_times > 0)
|
|||
|
{
|
|||
|
_times--;
|
|||
|
if (_times == 0)
|
|||
|
_status = 2; //ending
|
|||
|
else
|
|||
|
_status = 1; //new loop
|
|||
|
}
|
|||
|
else if (_start != 0)
|
|||
|
_status = 1; //new loop
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void DrawFrame()
|
|||
|
{
|
|||
|
if (_frameCount > 0)
|
|||
|
{
|
|||
|
Frame frame = _frames[_frame];
|
|||
|
graphics.texture = frame.texture;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|