Does Unity support Animated GIFS? If yes, is there anything special I need to do in order for the animated GIFS to actually function properly on game objects or GUI textures? I'd like to use them as textures on objects such as water, lava, etc =) Any information is greatly appreciated! Thank you! --Velk
Nope, but you can save the individual frames as separate textures, and cycle through an array of those textures. In some cases (if you don't need tiling, for example), you can save all the frames into one texture and animate the texture offset. I think there's a script on the wiki for that. --Eric
Thanks Eric5h5, Thanks for the information...do you know how I can tell Unity to cycle through a series of textures (specifically, animated GIFS?) I'd like to use Animated GIFS as textures in my game. So far, I've tried attaching the following script to my gameobject with the Animated GIF as it's material/texture: Code (csharp): // this line of code will make the Movie Texture begin playing renderer.material.mainTexture.Play(); Any ideas? I'm still learning how to script -- so any information is greatly appreciated. Thank you!
As I said, you can't use animated GIFs, but you can save the individual frames as separate textures, and cycle through an array of those textures: Code (csharp): var frames : Texture[]; var framesPerSecond = 10; function Update() { var index : int = (Time.time * framesPerSecond) % frames.Length; renderer.material.mainTexture = frames[index]; } --Eric
Thank you so much for the amazing script Eric5h5! It works really well and solved my question(s) =) Now that I've experimented with some of the possibilities of animated GIFS in Unity...I was wondering if it would also be possible to import a movie (.mov, .mpeg, etc) and have Unity simply play the movie at 10 frames per second. It is much easier for me to set what frames play per second compared to manually importing each image and linking them all to the textures within the script you provided me -- thanks again for the script . Does that make sense? Any information is helpful =) Thanks! --Velk
Yes; see "MovieTexture" in the docs for that. However, that only works with Pro. Also, it's intended for actual movies rather than animated textures like water, etc.--there's overhead for decompressing movies on the fly that you wouldn't want with continuously animated textures, not to mention that you can't use alpha channels in movies. I know having separate frames isn't the most convenient thing ever, but it's unlikely you have too many frames for animated textures due to memory concerns. --Eric
Thanks for the information/quick response =) I'll stick with the script you posted -- however, I have been trying to figure out a way to have a variable on the script that I can adjust from the Inspector. This would allow me the ability set a specific frame that I'd like the "Animated GIF" to stop on. Here is what I've tried so far: Code (csharp): WrapMode.ClampForever What should I add to the script shown BELOW in order for it to allow my GIF animation to stop on a desired frame, preferably a variable I can tweak from the Inspector... Code (csharp): var frames : Texture[]; var framesPerSecond = 10; function Update() { var index : int = (Time.time * framesPerSecond) % frames.Length; renderer.material.mainTexture = frames[index]; } Once again, thank you for your help -- any additional information is always appreciated =) --Velk
That's for animations on 3D objects. To stop on a desired frame, you could make a variable that's exposed to the inspector, and in the Update function, compare that to the "index" variable, and only have the rest of the code run if "index" is less than or equal to that value. --Eric
There has to be a way to stop the script from cycling through the image sequence repeatedly. I've tried all kinds of additional code...nothing seems to stop the infamous GIF sequence from playing in Unity. Any ideas? I'm an Arts guy more than a programmer so a line of code or a website link where I can find the information and research it would be much appreciated =) Thanks again! --Velk
But this doesn't work for GUITextures as the poster originally requested. How does one animate GUITextures (no meshes)
Instead of using renderer.material.mainTexture, you can assign the GUITexture's texture property. Otherwise, the code is the same.
This is C# Start () .... public Texture2D []frames; OnGUI ()..... (instead of Update) int index = (int) (Time.time * framesPerSecond) % frames.Length;
Using ZNE GIF as a Menu Background SOLVED: Turns out my GIF is 1024 x 768 x 1 byte x 300 frames. But ZNE expands it to 1024x768x4x300 thus 943 MB. Oops. Changed the type to a GIF Movie and now memory use is fine. (Not set to Load All Frames at first) --------------------------------------- I got ZNE GIF and it crashes. I share a GUITexture, and a single Zne Gif Animation (Script)so I call update in each of my menu objects. Sitting in a menu doing nothing else uses up memory vey fast. 3.5 GB ram in about 10 seconds:!: I narrowed it down to the line Code (csharp): z.Update_Frame(); Notes: (Also tried GifComponent_Update() and it has the same problem) (The gif is 3.6 MB on disk, a full screen background) (If I set to Load all frames at first, it burns up 2.3 GB of memory, then is stable) (Loading in a image viewer only takes 31 MB for the whole viewer and image) (My app is about 800MB after start up, in menus, not in-game yet, if I delete the ZNE Gif component.) (Starting ZNE GIF alone takes about 1.7 GB, even if Zne Gif Animation is disabled, and the gif file removed) Any ideas why? Called from Update in all menu components: (Except the one menu that 'owns' the zneGifAnimation) Code (csharp): public void _updateMenuBackgroundAnimation() { Note: (This has been changed to be zneGifMovie instead) zneGifAnimation z = MainMenu.thisInstance.GetComponent<zneGifAnimation>(); if(z != null) { z.Update_Frame(); } } Then to draw it as a menu background: Code (csharp): public void fillMenuBackground() { Texture t = mainMenuBackground; if(MainMenu.thisInstance.guiTexture != null) { t = MainMenu.thisInstance.guiTexture.texture; } GUI.DrawTexture( new Rect(0,0,Screen.width, Screen.height), t, ScaleMode.StretchToFill); }
You could also try a script like the following, which makes use of Mono's System.Drawing library: http://wiki.unity3d.com/index.php/AnimatedGifDrawer
or just think outside the box, and use tools unity provides in fun ways. I like to avoid any heavy scripting. I was working on replicating the Deadspace style of GUI for doors, ect. First i made my GUI images for the layers and made them 75% occ in gimp, and made the rest Trans on alpha. In Unity I just put them on very thin cubes. Layering the ultra thin cubes(with image textures, set to trans/Diffuse). then here is the lol part, just make animations in the animator and let them loop forever of them spinning. Of course a little java to make them spin, appear on collision, ect would be very easy as well. In the end the player sees your animated "texture" the way u want them to see. also works great for cheat gui, attach the planes to the camera, bam poor mans gui. Always find a way to cheat the system.
You can try converting the gif to an mp4 or other video format and then set that as a VideoTexture. It would still need a script to play, but it would be significantly simpler. Here is the VideoTexture tutorial: http://docs.unity3d.com/Manual/class-MovieTexture.html As for gif to mp4 tools, there are plenty online converters out there.
Hi everybody, I've found a really nice solution called UniGif. You can find the repository here: https://github.com/WestHillApps/UniGif Tested on Android, iOS, MacOS, Windows and Editor. May need some changes if load from StreamingAssets (Android). Cheers, Jaime
I had struggled a fair bit trying to get this done. So, putting it out there in case it helps someone. Requirement was to retrieve spritesheet stored as ByteStream from a SQLite file and cycle through each of these sprites to make it look like a gif. To achieve this, I retrieve data from SQLite at the start of the scene and store it in a static class. I also create an empty sprite with default scale and rotation to be visible in your camera. Then create a new script under this sprite. Script is below. You can change the location of code from OnEnable to anything that suits your need. Code (CSharp): public class imageController : MonoBehaviour { private int counter; private int rows; private int cols; private Sprite rawImage; public GameObject mainActor; private Sprite[] individualImages; private void OnDisable() { this.individualImages = null; base.CancelInvoke(); } private void OnEnable() { this.individualImages = null; base.CancelInvoke(); this.counter = 0; byte[] data = DBBean.bytMedia[DBBean.currentRecord]; this.rows = DBBean.intRows[DBBean.currentRecord]; this.cols = DBBean.intCols[DBBean.currentRecord]; Texture2D texture2D = new Texture2D(1, 1); texture2D.LoadImage(data); this.rawImage = Sprite.Create(texture2D, new Rect(0f, 0f, (float)texture2D.width, (float)texture2D.height), new Vector2(0.2f, 0.2f)); float height = this.rawImage.rect.height; float width = this.rawImage.rect.width; float num = width / (float)this.cols; float num2 = height / (float)this.rows; int num3 = 0; this.individualImages = new Sprite[this.rows * this.cols]; for (int i = 0; i < this.rows; i++) { for (int j = this.cols - 1; j > -1; j--) { Color[] pixels = texture2D.GetPixels((int)num * j, (int)num2 * i, (int)num, (int)num2); Texture2D texture2D2 = new Texture2D((int)num, (int)num2); texture2D2.SetPixels(0, 0, (int)num, (int)num2, pixels); texture2D2.Apply(); this.individualImages[num3] = Sprite.Create(texture2D2, new Rect(0f, 0f, (float)texture2D2.width, (float)texture2D2.height), new Vector2(0.2f, 0.2f)); num3++; } } base.InvokeRepeating("RenderSprites", 0.001f, DBBean.flAnimationInterval[DBBean.currentRecord]); this.counter = this.individualImages.Length - 1; } private void RenderSprites() { if (this.counter < 0) { this.counter = this.individualImages.Length - 1; } this.mainActor.GetComponent<SpriteRenderer>().sprite = this.individualImages[this.counter]; this.mainActor.transform.localScale = new Vector3(DBBean.flScalex[DBBean.currentRecord], DBBean.flScaley[DBBean.currentRecord], DBBean.flScalez[DBBean.currentRecord]); this.mainActor.transform.position = new Vector3(DBBean.flCoordinatex[DBBean.currentRecord], DBBean.flCoordinatey[DBBean.currentRecord], DBBean.flCoordinatez[DBBean.currentRecord]); this.mainActor.transform.eulerAngles = new Vector3(DBBean.flRotatex[DBBean.currentRecord], DBBean.flRotatey[DBBean.currentRecord], DBBean.flRotatez[DBBean.currentRecord]); this.counter--; } } Edit : I realised that the above code freezes the camera when sprites are created from the spritesheet(>150 images, 255X425pixels). I could improve the performance by converting the stuff in OnEnable to a Coroutine & invoking it from OnEnable, also made OnEnable to run InvokeRepeating. Since Texture.Load and Sprite.Create takes up too much time, I used 'yield return null' to pause coroutine execution momentarily, to reduce the screen freeze.
Try this method: 1. Go to https://ezgif.com/split to split your animated gif into frames. 2. Download the zip file and extract all the images to a folder in your project. 3. Copy/Paste the code below in a C# script called ExplosionController(or whatever you want) NOTE: If you down't call the script ExplosionController, make sure to change the "ExplosionController" line in the code to whatever your filename is. Code (CSharp): using UnityEngine; using UnityEngine.UI; using System.Collections; public class ExplosionController : MonoBehaviour { public Sprite[] frames; public Image explosion; public float frameRate = 0.1f; private int currentImage; // Use this for initialization void Start () { currentImage = 0; InvokeRepeating ("ChangeImage", 0.1f, frameRate); } private void ChangeImage() { if (currentImage == frames.Length - 1) { CancelInvoke("ChangeImage"); Destroy (explosion); } currentImage += 1; explosion.sprite = frames [currentImage]; } } 4. Change the variables (if you want) 5. Make an Image and an empty GameObject with the script attached to it. 6. Add all your frames to the list "Frames" in the inspector. Also, attach the Image to the GameObject that you created above. 7. All done!!!
It's also possible to deal with that in JS if you simply use the following piece of code provided in a solution available on this answer: Code (JavaScript): var frames : Texture2D[]; var framesPorSegundo = 10.0; function Update() { var index : int = Time.time * framesPorSegundo; index = index % frames.Length; GetComponent.< Renderer > ().material.mainTexture = frames[index]; } There's also this video showing the process. I tried the last solution provided here, but I don't know exactly why it was easier to deal with this issue by following this specific way which works following the same steps described by megarg. It's important to notice the GIF here will auto repeat.
C# code Code (CSharp): using System.Collections; using System.Collections.Generic; using UnityEngine; public class GIF_Manager : MonoBehaviour { //frames [SerializeField] Texture[] Frames; // speed [SerializeField] float framesPerSecond = 10f; void Update() { // get index of frame int index = (int)(Time.time * framesPerSecond) % Frames.Length; // check if the Texture array don't equal null if (Frames[index] != null) { // get Renderer of this gameobject this.gameObject.GetComponent<Renderer>().material.mainTexture = Frames[index]; } } } this website for disassembly GIF image online https://ezgif.com/split download your list of images and import to unity.
If you just import an image sequence and then drag all the images into the scene view, unity automatically creates an anim and plays through your image sequence.
Hi! I'm developing my own GIF library - Power GIF. It's available on the Asset Store: https://assetstore.unity.com/packages/tools/animation/power-gif-120039
This works 2021 still on C#. All GIF Animators have been deprecated on Asset Store also YouTube tutorials. Thank you for this code!