/*
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.Networking;
using UnityEngine.UI;
///
/// Texture Animation from GIF image
///
[RequireComponent(typeof(UniGifImageAspectController))]
public class UniGifImage : MonoBehaviour
{
///
/// This component state
///
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 m_gifTextureList;
// Delay time
private float m_delayTime;
// Texture index
private int m_gifTextureIndex;
// loop counter
private int m_nowLoopCount;
///
/// Now state
///
public State nowState
{
get;
private set;
}
///
/// Animation loop count (0 is infinite)
///
public int loopCount
{
get;
private set;
}
///
/// Texture width (px)
///
public int width
{
get;
private set;
}
///
/// Texture height (px)
///
public int height
{
get;
private set;
}
private void Start()
{
if (m_rawImage == null)
{
m_rawImage = GetComponent();
}
if (m_loadOnStart)
{
SetGifFromUrl(m_loadOnStartUrl);
}
}
private void OnDestroy()
{
Clear();
}
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;
}
// Change texture
m_gifTextureIndex++;
if (m_gifTextureIndex >= m_gifTextureList.Count)
{
m_gifTextureIndex = 0;
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;
}
}
///
/// Set GIF texture from url
///
/// GIF image url (WEB or StreamingAssets path)
/// Auto play after decode
public void SetGifFromUrl(string url, bool autoPlay = true)
{
StartCoroutine(SetGifFromUrlCoroutine(url, autoPlay));
}
///
/// Set GIF texture from url
///
/// GIF image url (WEB or StreamingAssets path)
/// Auto play after decode
/// IEnumerator
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("file:///" + Application.streamingAssetsPath, url);
}
// Load file
UnityWebRequest request = UnityWebRequest.Get(path);
request.SendWebRequest();
while (!request.isDone)
{
yield return null;
}
if (string.IsNullOrEmpty(request.error) == false)
{
Debug.LogError("File load error.\n" + request.error + "\npath: " + path);
nowState = State.None;
yield break;
}
Clear();
nowState = State.Loading;
// Get GIF textures
yield return StartCoroutine(UniGif.GetTextureListCoroutine(request.downloadHandler.data, (gifTexList, loopCount, width, height) =>
{
request.Dispose();
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));
}
///
/// Clear GIF texture
///
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;
}
///
/// Play GIF animation
///
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;
}
///
/// Stop GIF animation
///
public void Stop()
{
if (nowState != State.Playing && nowState != State.Pause)
{
Debug.LogWarning("State is not Playing and Pause.");
return;
}
nowState = State.Ready;
}
///
/// Pause GIF animation
///
public void Pause()
{
if (nowState != State.Playing)
{
Debug.LogWarning("State is not Playing.");
return;
}
nowState = State.Pause;
}
///
/// Resume GIF animation
///
public void Resume()
{
if (nowState != State.Pause)
{
Debug.LogWarning("State is not Pause.");
return;
}
nowState = State.Playing;
}
}