Unity Udexreal开发插件包
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

/*
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;
}
}