一、Image
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
using System;
[RequireComponent(typeof(Image))]
public class GifPlayer_Image : MonoBehaviour
{
[SerializeField, Header("是否启用加载模式")]
bool isResourcesLoading;
[SerializeField]
Sprite[] frames;
[SerializeField]
Image image;
[SerializeField, Range(0, 30), Header("帧率")]
float framesRatio = 25f;
[Header("当前帧图片"), SerializeField]
Texture2D currentFrameTex;
[Header("序列帧路径,Resources 文件加下")]
public string m_Path;
[Header("最大循环帧数"), Range(0, 500)]
public int framesMax;
[SerializeField, Header("当前帧")]
int frameIndex = 0;
bool ignoreTimeScale = true;
[SerializeField, Header("是否循环")]
bool loop = false;
float mUpdate = 0f;
[SerializeField, Header("是否激活Gif")]
bool isActive;
[SerializeField, Header("是否使用事件")]
bool isUsingEvent;
public UnityEvent onComplete;
/// <summary>
/// Returns is the animation is still playing or not
/// </summary>
public bool isPlaying
{
get { return enabled; }
}
/// <summary>
/// Real time since startup.
/// </summary>
public float RealTime
{
get { return UnityEngine.Time.unscaledTime; }
}
/// <summary>
/// Real delta time.
/// </summary>
public float RealDeltaTime
{
get { return UnityEngine.Time.unscaledDeltaTime; }
}
public void Start()
{
if (!image)
{
image = GetComponent<Image>();
}
}
public void SetActive(bool value)
{
isActive = value;
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (image != null && framesLength > 0)
{
if (!enabled && !loop)
{
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (newIndex < 0 || newIndex >= framesLength)
{
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
}
}
enabled = true;
UpdateSprite();
}
}
/// <summary>
/// 暂停序列帧动画
/// </summary>
public void Pause() { enabled = false; }
/// <summary>
/// 继续播放
/// </summary>
public void GoOn() { enabled = true; }
/// <summary>
/// 重置序列帧事件
/// </summary>
public void ResetEvent()
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
Resources.UnloadAsset(currentFrameTex);
frameIndex = 0;
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
UpdateSprite();
isActive = false;
}
/// <summary>
/// 设置RawImage初始图片
/// </summary>
/// <param name="texture"></param>
public void SetRawImageStartSprite(Sprite texture)
{
if (image)
{
image.sprite = texture;
}
}
void Update()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (framesLength == 0)
{
enabled = false;
}
else if (framesRatio != 0)
{
float time = ignoreTimeScale ? RealTime : Time.time;
if (mUpdate < time)
{
mUpdate = time;
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (!loop && (newIndex < 0 || newIndex >= framesLength))
{
enabled = false;
return;
}
frameIndex = RepeatIndex(newIndex, framesLength);
UpdateSprite();
}
}
}
}
/// <summary>
/// 立即更新可见的精灵。
/// </summary>
void UpdateSprite()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
float time = ignoreTimeScale ? RealTime : Time.time;
if (framesRatio != 0)
{
mUpdate = time + Mathf.Abs(1f / framesRatio);
}
if (image != null)
{
if (!isResourcesLoading)
{
image.sprite = frames[frameIndex];
}
else
{
Resources.UnloadAsset(currentFrameTex);
currentFrameTex = (Texture2D)(Resources.Load(m_Path + "/" + frameIndex.ToString()) as Texture2D);
image.sprite = Sprite.Create(currentFrameTex, new Rect(0, 0, currentFrameTex.width, currentFrameTex.height), new Vector2(0.5f, 0.5f));
}
}
if (!loop)
{
//-判断当 数字模拟完成后,要执行事件-//
if (isUsingEvent && frameIndex == framesLength - 1)
{
onComplete.Invoke();
}
}
}
}
/// <summary>
/// 使用重复逻辑包装索引,以便例如+1过去的结果意味着索引为'1'。
/// </summary>
[System.Diagnostics.DebuggerHidden]
[System.Diagnostics.DebuggerStepThrough]
private int RepeatIndex(int val, int max)
{
if (max < 1) return 0;
while (val < 0) val += max;
while (val >= max) val -= max;
return val;
}
}
二、RawImage
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
using System;
[RequireComponent(typeof(RawImage))]
public class GifPlayer_RawImage : MonoBehaviour
{
[SerializeField, Header("是否启用加载模式")]
bool isResourcesLoading;
[SerializeField]
Texture[] frames;
[SerializeField]
RawImage rawImage;
[SerializeField, Range(0, 30), Header("帧率")]
float framesRatio = 25f;
[Header("当前帧图片"), SerializeField]
Texture currentFrameTex;
[Header("序列帧路径,Resources 文件加下")]
public string m_Path;
[Header("最大循环帧数"), Range(0, 500)]
public int framesMax;
[SerializeField, Header("当前帧")]
int frameIndex = 0;
bool ignoreTimeScale = true;
[SerializeField, Header("是否循环")]
bool loop = false;
float mUpdate = 0f;
[SerializeField, Header("是否激活Gif")]
bool isActive;
[SerializeField, Header("是否使用事件")]
bool isUsingEvent;
public UnityEvent onComplete;
/// <summary>
/// Returns is the animation is still playing or not
/// </summary>
public bool isPlaying
{
get { return enabled; }
}
/// <summary>
/// Real time since startup.
/// </summary>
public float RealTime
{
get { return UnityEngine.Time.unscaledTime; }
}
/// <summary>
/// Real delta time.
/// </summary>
public float RealDeltaTime
{
get { return UnityEngine.Time.unscaledDeltaTime; }
}
public void Start()
{
if (!rawImage)
{
rawImage = gameObject.GetComponent<RawImage>();
}
}
public void SetActive(bool value)
{
isActive = value;
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (rawImage != null && framesLength > 0)
{
StopCoroutine("FrameAnimationEnd");
if (!enabled && !loop)
{
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (newIndex < 0 || newIndex >= framesLength)
{
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
}
}
enabled = true;
UpdateSprite();
}
}
/// <summary>
/// 暂停序列帧动画
/// </summary>
public void Pause() { enabled = false; }
/// <summary>
/// 继续播放
/// </summary>
public void GoOn() { enabled = true; }
/// <summary>
/// 重置序列帧事件
/// </summary>
public void ResetEvent()
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
Resources.UnloadAsset(currentFrameTex);
frameIndex = 0;
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
UpdateSprite();
isActive = false;
}
/// <summary>
/// 设置RawImage初始图片
/// </summary>
/// <param name="texture"></param>
public void SetRawImageStartSprite(Texture texture)
{
if (rawImage)
{
rawImage.texture = texture;
}
}
void Update()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (framesLength == 0)
{
enabled = false;
}
else if (framesRatio != 0)
{
float time = ignoreTimeScale ? RealTime : Time.time;
if (mUpdate < time)
{
mUpdate = time;
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (!loop && (newIndex < 0 || newIndex >= framesLength))
{
enabled = false;
return;
}
frameIndex = RepeatIndex(newIndex, framesLength);
UpdateSprite();
}
}
}
}
/// <summary>
/// 立即更新可见的精灵。
/// </summary>
void UpdateSprite()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
float time = ignoreTimeScale ? RealTime : Time.time;
if (framesRatio != 0)
{
mUpdate = time + Mathf.Abs(1f / framesRatio);
}
if (rawImage != null)
{
if (!isResourcesLoading)
{
rawImage.texture = frames[frameIndex];
}
else
{
Resources.UnloadAsset(currentFrameTex);
currentFrameTex = (Texture)(Resources.Load(m_Path + "/" + frameIndex.ToString()) as Texture2D);
rawImage.texture = currentFrameTex;
}
}
if (!loop)
{
//-判断当 数字模拟完成后,要执行事件-//
if (isUsingEvent && frameIndex == framesLength - 1)
{
onComplete.Invoke();
}
}
}
}
/// <summary>
/// 使用重复逻辑包装索引,以便例如+1过去的结果意味着索引为'1'。
/// </summary>
[System.Diagnostics.DebuggerHidden]
[System.Diagnostics.DebuggerStepThrough]
private int RepeatIndex(int val, int max)
{
if (max < 1) return 0;
while (val < 0) val += max;
while (val >= max) val -= max;
return val;
}
}
三、Material
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using System.Collections;
using System;
[RequireComponent(typeof(MeshRenderer))]
public class GifPlayer_Material : MonoBehaviour
{
[SerializeField, Header("是否启用加载模式")]
bool isResourcesLoading;
[SerializeField, Header("序列帧数组")]
Texture[] frames;
[SerializeField]
Material mat;
[SerializeField, Range(0, 30), Header("帧率")]
float framesRatio = 25f;
[Header("当前帧图片"), SerializeField]
Texture currentFrameTex;
[Header("序列帧路径,Resources 文件加下")]
public string m_Path;
[Header("最大循环帧数"), Range(0, 500)]
public int framesMax;
[SerializeField, Header("当前帧")]
int frameIndex = 0;
bool ignoreTimeScale = true;
[SerializeField, Header("是否循环")]
bool loop = false;
float mUpdate = 0f;
[SerializeField, Header("是否激活Gif")]
bool isActive;
[SerializeField, Header("是否使用事件")]
bool isUsingEvent;
public UnityEvent onComplete;
/// <summary>
/// Returns is the animation is still playing or not
/// </summary>
public bool isPlaying
{
get { return enabled; }
}
/// <summary>
/// Real time since startup.
/// </summary>
public float RealTime
{
get { return UnityEngine.Time.unscaledTime; }
}
/// <summary>
/// Real delta time.
/// </summary>
public float RealDeltaTime
{
get { return UnityEngine.Time.unscaledDeltaTime; }
}
public void Start()
{
if (!mat)
{
mat = GetComponent<MeshRenderer>().sharedMaterial;
}
}
public void SetActive(bool value)
{
isActive = value;
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (mat != null && framesLength > 0)
{
if (!enabled && !loop)
{
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (newIndex < 0 || newIndex >= framesLength)
{
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
}
}
enabled = true;
UpdateSprite();
}
}
/// <summary>
/// 暂停序列帧动画
/// </summary>
public void Pause() { enabled = false; }
/// <summary>
/// 继续播放
/// </summary>
public void GoOn() { enabled = true; }
/// <summary>
/// 重置序列帧事件
/// </summary>
public void ResetEvent()
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
Resources.UnloadAsset(currentFrameTex);
frameIndex = 0;
frameIndex = framesRatio < 0 ? framesLength - 1 : 0;
UpdateSprite();
isActive = false;
}
/// <summary>
/// 设置RawImage初始图片
/// </summary>
/// <param name="texture"></param>
public void SetRawImageStartSprite(Texture texture)
{
if (mat)
{
mat.mainTexture = texture;
}
}
void Update()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
if (framesLength == 0)
{
enabled = false;
}
else if (framesRatio != 0)
{
float time = ignoreTimeScale ? RealTime : Time.time;
if (mUpdate < time)
{
mUpdate = time;
int newIndex = framesRatio > 0 ? frameIndex + 1 : frameIndex - 1;
if (!loop && (newIndex < 0 || newIndex >= framesLength))
{
enabled = false;
return;
}
frameIndex = RepeatIndex(newIndex, framesLength);
UpdateSprite();
}
}
}
}
/// <summary>
/// 立即更新可见的精灵。
/// </summary>
void UpdateSprite()
{
if (isActive)
{
int framesLength = 0;
if (!isResourcesLoading)
{
framesLength = frames.Length;
}
else
{
framesLength = framesMax;
}
float time = ignoreTimeScale ? RealTime : Time.time;
if (framesRatio != 0)
{
mUpdate = time + Mathf.Abs(1f / framesRatio);
}
if (mat != null)
{
if (!isResourcesLoading)
{
mat.mainTexture = frames[frameIndex];
}
else
{
Resources.UnloadAsset(currentFrameTex);
currentFrameTex = (Texture)(Resources.Load(m_Path + "/" + frameIndex.ToString()) as Texture2D);
mat.mainTexture = currentFrameTex;
}
}
if (!loop)
{
//-判断当 数字模拟完成后,要执行事件-//
if (isUsingEvent && frameIndex == framesLength - 1)
{
onComplete.Invoke();
}
}
}
}
/// <summary>
/// 使用重复逻辑包装索引,以便例如+1过去的结果意味着索引为'1'。
/// </summary>
[System.Diagnostics.DebuggerHidden]
[System.Diagnostics.DebuggerStepThrough]
private int RepeatIndex(int val, int max)
{
if (max < 1) return 0;
while (val < 0) val += max;
while (val >= max) val -= max;
return val;
}
}