You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
388 lines
9.5 KiB
388 lines
9.5 KiB
/* |
|
UniGif |
|
Copyright (c) 2015 WestHillApps (Hironari Nishioka) |
|
This software is released under the MIT License. |
|
http://opensource.org/licenses/mit-license.php |
|
*/ |
|
|
|
using System.Collections; |
|
using System.Collections.Generic; |
|
using System.IO; |
|
using UnityEngine; |
|
using UnityEngine.UI; |
|
|
|
/// <summary> |
|
/// Texture Animation from GIF image |
|
/// </summary> |
|
public class UniGifImage : MonoBehaviour |
|
{ |
|
/// <summary> |
|
/// This component state |
|
/// </summary> |
|
public enum State |
|
{ |
|
None, |
|
Loading, |
|
Ready, |
|
Playing, |
|
Pause, |
|
} |
|
|
|
// Target row image |
|
[SerializeField] |
|
private RawImage m_rawImage; |
|
// Image Aspect Controller |
|
[SerializeField] |
|
private UniGifImageAspectController m_imgAspectCtrl; |
|
// Textures filter mode |
|
[SerializeField] |
|
private FilterMode m_filterMode = FilterMode.Point; |
|
// Textures wrap mode |
|
[SerializeField] |
|
private TextureWrapMode m_wrapMode = TextureWrapMode.Clamp; |
|
// Load from url on start |
|
[SerializeField] |
|
private bool m_loadOnStart; |
|
// GIF image url (WEB or StreamingAssets path) |
|
[SerializeField] |
|
private string m_loadOnStartUrl; |
|
// Rotating on loading |
|
[SerializeField] |
|
private bool m_rotateOnLoading; |
|
// Debug log flag |
|
[SerializeField] |
|
private bool m_outputDebugLog; |
|
|
|
// Decoded GIF texture list |
|
private List<UniGif.GifTexture> m_gifTextureList; |
|
// Delay time |
|
private float m_delayTime; |
|
// Texture index |
|
private int m_gifTextureIndex; |
|
// loop counter |
|
private int m_nowLoopCount; |
|
|
|
/// <summary> |
|
/// Now state |
|
/// </summary> |
|
public State nowState |
|
{ |
|
get; |
|
private set; |
|
} |
|
|
|
/// <summary> |
|
/// Animation loop count (0 is infinite) |
|
/// </summary> |
|
public int loopCount |
|
{ |
|
get; |
|
private set; |
|
} |
|
|
|
/// <summary> |
|
/// Texture width (px) |
|
/// </summary> |
|
public int width |
|
{ |
|
get; |
|
private set; |
|
} |
|
|
|
/// <summary> |
|
/// Texture height (px) |
|
/// </summary> |
|
public int height |
|
{ |
|
get; |
|
private set; |
|
} |
|
|
|
private void Awake() |
|
{ |
|
if (m_rawImage == null) |
|
{ |
|
m_rawImage = GetComponent<RawImage>(); |
|
} |
|
if (m_loadOnStart) |
|
{ |
|
SetGifFromUrl(m_loadOnStartUrl); |
|
} |
|
} |
|
|
|
private void Start() |
|
{ |
|
//if (m_rawImage == null) |
|
//{ |
|
// m_rawImage = GetComponent<RawImage>(); |
|
//} |
|
//if (m_loadOnStart) |
|
//{ |
|
// SetGifFromUrl(m_loadOnStartUrl); |
|
//} |
|
} |
|
|
|
private void OnDestroy() |
|
{ |
|
Clear(); |
|
} |
|
|
|
public void ResetGif() |
|
{ |
|
m_rawImage.texture = m_gifTextureList[0].m_texture2d; |
|
m_delayTime = Time.time + m_gifTextureList[0].m_delaySec; |
|
} |
|
|
|
float time = 0; |
|
|
|
private void Update() |
|
{ |
|
switch (nowState) |
|
{ |
|
case State.None: |
|
break; |
|
|
|
case State.Loading: |
|
if (m_rotateOnLoading) |
|
{ |
|
transform.Rotate(0f, 0f, 30f * Time.deltaTime, Space.Self); |
|
} |
|
break; |
|
|
|
case State.Ready: |
|
break; |
|
|
|
case State.Playing: |
|
if (m_rawImage == null || m_gifTextureList == null || m_gifTextureList.Count <= 0) |
|
{ |
|
return; |
|
} |
|
if (m_delayTime > Time.time) |
|
{ |
|
return; |
|
} |
|
|
|
time += Time.deltaTime; |
|
// Change texture |
|
if (time >= 0.022f) |
|
{ |
|
m_gifTextureIndex++; |
|
time -= 0.022f; |
|
} |
|
if (m_gifTextureIndex >= m_gifTextureList.Count) |
|
{ |
|
Stop(); |
|
m_gifTextureIndex = 0; |
|
return; |
|
|
|
if (loopCount > 0) |
|
{ |
|
m_nowLoopCount++; |
|
if (m_nowLoopCount >= loopCount) |
|
{ |
|
Stop(); |
|
return; |
|
} |
|
} |
|
} |
|
|
|
m_rawImage.texture = m_gifTextureList[m_gifTextureIndex].m_texture2d; |
|
m_delayTime = Time.time + m_gifTextureList[m_gifTextureIndex].m_delaySec; |
|
break; |
|
|
|
case State.Pause: |
|
break; |
|
|
|
default: |
|
break; |
|
} |
|
} |
|
|
|
public void Replay() |
|
{ |
|
SetGifFromUrl(m_loadOnStartUrl); |
|
} |
|
|
|
/// <summary> |
|
/// Set GIF texture from url |
|
/// </summary> |
|
/// <param name="url">GIF image url (WEB or StreamingAssets path)</param> |
|
/// <param name="autoPlay">Auto play after decode</param> |
|
public void SetGifFromUrl(string url, bool autoPlay = true) |
|
{ |
|
StartCoroutine(SetGifFromUrlCoroutine(url, autoPlay)); |
|
} |
|
|
|
/// <summary> |
|
/// Set GIF texture from url |
|
/// </summary> |
|
/// <param name="url">GIF image url (WEB or StreamingAssets path)</param> |
|
/// <param name="autoPlay">Auto play after decode</param> |
|
/// <returns>IEnumerator</returns> |
|
public IEnumerator SetGifFromUrlCoroutine(string url, bool autoPlay = true) |
|
{ |
|
if (string.IsNullOrEmpty(url)) |
|
{ |
|
Debug.LogError("URL is nothing."); |
|
yield break; |
|
} |
|
|
|
if (nowState == State.Loading) |
|
{ |
|
Debug.LogWarning("Already loading."); |
|
yield break; |
|
} |
|
nowState = State.Loading; |
|
|
|
string path; |
|
if (url.StartsWith("http")) |
|
{ |
|
// from WEB |
|
path = url; |
|
} |
|
else |
|
{ |
|
// from StreamingAssets |
|
path = Path.Combine(Application.streamingAssetsPath, url); |
|
} |
|
|
|
// Load file |
|
using (WWW www = new WWW(path)) |
|
{ |
|
yield return www; |
|
|
|
if (string.IsNullOrEmpty(www.error) == false) |
|
{ |
|
Debug.LogError("File load error.\n" + www.error); |
|
nowState = State.None; |
|
yield break; |
|
} |
|
|
|
//Clear(); |
|
nowState = State.Loading; |
|
|
|
// Get GIF textures |
|
yield return StartCoroutine(UniGif.GetTextureListCoroutine(www.bytes, (gifTexList, loopCount, width, height) => |
|
{ |
|
if (gifTexList != null) |
|
{ |
|
m_gifTextureList = gifTexList; |
|
this.loopCount = loopCount; |
|
this.width = width; |
|
this.height = height; |
|
nowState = State.Ready; |
|
|
|
m_imgAspectCtrl.FixAspectRatio(width, height); |
|
|
|
if (m_rotateOnLoading) |
|
{ |
|
transform.localEulerAngles = Vector3.zero; |
|
} |
|
|
|
if (autoPlay) |
|
{ |
|
Play(); |
|
} |
|
} |
|
else |
|
{ |
|
Debug.LogError("Gif texture get error."); |
|
nowState = State.None; |
|
} |
|
}, |
|
m_filterMode, m_wrapMode, m_outputDebugLog)); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// Clear GIF texture |
|
/// </summary> |
|
public void Clear() |
|
{ |
|
if (m_rawImage != null) |
|
{ |
|
m_rawImage.texture = null; |
|
} |
|
|
|
if (m_gifTextureList != null) |
|
{ |
|
for (int i = 0; i < m_gifTextureList.Count; i++) |
|
{ |
|
if (m_gifTextureList[i] != null) |
|
{ |
|
if (m_gifTextureList[i].m_texture2d != null) |
|
{ |
|
Destroy(m_gifTextureList[i].m_texture2d); |
|
m_gifTextureList[i].m_texture2d = null; |
|
} |
|
m_gifTextureList[i] = null; |
|
} |
|
} |
|
m_gifTextureList.Clear(); |
|
m_gifTextureList = null; |
|
} |
|
|
|
nowState = State.None; |
|
} |
|
|
|
/// <summary> |
|
/// Play GIF animation |
|
/// </summary> |
|
public void Play() |
|
{ |
|
if (nowState != State.Ready) |
|
{ |
|
Debug.LogWarning("State is not READY."); |
|
return; |
|
} |
|
if (m_rawImage == null || m_gifTextureList == null || m_gifTextureList.Count <= 0) |
|
{ |
|
Debug.LogError("Raw Image or GIF Texture is nothing."); |
|
return; |
|
} |
|
nowState = State.Playing; |
|
m_rawImage.texture = m_gifTextureList[0].m_texture2d; |
|
m_delayTime = Time.time + m_gifTextureList[0].m_delaySec; |
|
m_gifTextureIndex = 0; |
|
m_nowLoopCount = 0; |
|
} |
|
|
|
/// <summary> |
|
/// Stop GIF animation |
|
/// </summary> |
|
public void Stop() |
|
{ |
|
if (nowState != State.Playing && nowState != State.Pause) |
|
{ |
|
Debug.LogWarning("State is not Playing and Pause."); |
|
return; |
|
} |
|
nowState = State.Ready; |
|
} |
|
|
|
/// <summary> |
|
/// Pause GIF animation |
|
/// </summary> |
|
public void Pause() |
|
{ |
|
if (nowState != State.Playing) |
|
{ |
|
Debug.LogWarning("State is not Playing."); |
|
return; |
|
} |
|
nowState = State.Pause; |
|
} |
|
|
|
/// <summary> |
|
/// Resume GIF animation |
|
/// </summary> |
|
public void Resume() |
|
{ |
|
if (nowState != State.Pause) |
|
{ |
|
Debug.LogWarning("State is not Pause."); |
|
return; |
|
} |
|
nowState = State.Playing; |
|
} |
|
} |