Here’s an answer that takes a bit up front but allows you to work with the GIF directly without having to save individual files to disk and what not. It will also play it back at the correct speed by reading the per frame delay from the Gif file. Might be a better way out there but I haven’t found it without paying for it. Hopefully it works for you.
First you need to get the System.Drawing.dll and drop it into your Assets folder. For whatever reason it’s not available in the Unity default environment but is required to use that specific Image class. That file is likely located in the following location.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Drawing.dll
Create a new text file in the Assets folder and call that file mcs.rsp. Now add this text to that file and save it.
-r:System.Drawing.dll
Now create a new Gif.cs file and put the following code in it.
using System.Collections.Generic;
using System.Drawing;
using System;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using UnityEngine;
public class Gif : MonoBehaviour
{
public Image gifImage;
public float delay = 0.1f;
int frameCount = 0;
FrameDimension dimension;
public void loadGif(string filepath)
{
gifImage = Image.FromFile(filepath);
dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
frameCount = gifImage.GetFrameCount(dimension);
}
private static byte[] Bitmap2RawBytes(Bitmap bmp)
{
byte[] bytes;
byte[] copyToBytes;
BitmapData bitmapData;
IntPtr Iptr = IntPtr.Zero;
bytes = new byte[bmp.Width * bmp.Height * 4];
copyToBytes = new byte[bmp.Width * bmp.Height * 4];
bmp.RotateFlip(RotateFlipType.RotateNoneFlipX);
Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
bitmapData = bmp.LockBits(rect, ImageLockMode.ReadOnly, bmp.PixelFormat);
Iptr = bitmapData.Scan0;
Marshal.Copy(Iptr, bytes, 0, bytes.Length);
for (int i = 0; i < bytes.Length; i++)
{
copyToBytes[bytes.Length - 1 - i] = bytes*;*
}
bmp.UnlockBits(bitmapData);
return copyToBytes;
}
public List GetFrames()
{
List gifFrames = new List(frameCount);
for (int i = 0; i < frameCount; i++)
{
gifImage.SelectActiveFrame(dimension, i);
PropertyItem item = gifImage.GetPropertyItem(0x5100);
int frameDelay = (item.Value[0] + item.Value[1] * 256) * 10;
delay = frameDelay / 1000f;
var frame = new Bitmap(gifImage.Width, gifImage.Height);
System.Drawing.Graphics.FromImage(frame).DrawImage(gifImage, Point.Empty);
Texture2D texture = new Texture2D(frame.Width, frame.Height, TextureFormat.ARGB32, false);
texture.LoadRawTextureData(Bitmap2RawBytes(frame));
texture.Apply();
gifFrames.Add(texture);
}
return gifFrames;
}
}
----------
You can now use the files by doing something like this. Create an UI–>Image element. Place the following code in a new script called GifImageDraw.cs. Place that script on some game object. Then by pressing “G” it will display the animated GIF 3 times in a row.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class GifImageDraw : MonoBehaviour
{
public string gifPath = “”;
// This is the UI image object you created which is a child of “canvas”.
public GameObject imageGo;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.G))
{
GrabGifImage();
}
}
void GrabGifImage()
{
ShowGif(gifPath);
}
void ShowGif(string path)
{
GameObject imageGo = GameObject.Find(“RawImage”);
Gif gif = new Gif();
gif.loadGif(path);
RectTransform rect = imageGo.GetComponent();
List frames = gif.GetFrames();
RawImage rawImage = imageGo.GetComponent();
StartCoroutine(ShowGifFrames(rawImage, frames, gif.delay));
}
IEnumerator ShowGifFrames(RawImage rawImage, List frames, float delay)
{
if (delay < 0.05f)
delay = 0.05f;
// Go for 5 iterations for clarity
for (int i = 0; i < 3; i++)
{
foreach (Texture2D frame in frames)
{
rawImage.texture = frame as Texture;
yield return new WaitForSeconds(delay);
}
}
}
}