- Home /
Video Workaround in Unity
I've been trying to place all my images inside one gameObject and change its texture material depending on the frame rate & Time.time. I couldn't seem to find a workaround for converting my texture materials(objects) as an int so i could increment it as if it were an actual video with the right amount of FPS. I was also wondering if I could load a set of images inside one folder which can be located in multiple directories? I put comments in the code too.
Here is the code:
using UnityEngine;
using System.Collections;
//Dynamic Arrays require using collections.generics
using System.Collections.Generic; //Make a generic list?
public class VideoT : MonoBehaviour {
public List<int> totalpictures; //Public list
string imageFolderName = "Biglang Liko - Ron Henley feat (10-4-2013 6-42-24 PM)";
public bool MakeTexture= false;
//ArrayList pictures= new ArrayList();
//public int[0] totalpictures = 6000;
bool loop= false;
int counter= 0;
bool Film = true;
float PictureRateInSeconds = 1;
private float nextPic = 0;
Object[] texturesL; // all the pictures for the video treated as a list of objects
void Start (){
totalpictures = new List<int>()[6000];
if(Film == true){
PictureRateInSeconds = 0.04166666666666666666f;
}
//Object[] textures = Resources.LoadAll(imageFolderName);
texturesL = Resources.LoadAll(imageFolderName); //Is it possible to load resources from multiple directories? a->b->c->picturesfolder
int[] textures = texturesL as int; //
for(int i= 0; i < textures.Length; i++){
Debug.Log("found TEXTURES");
totalpictures.Add(textures[i]);
}
}
void Update (){
if(Time.time > nextPic){
nextPic = Time.time + PictureRateInSeconds; // FPS
counter += 1;
if(MakeTexture == true){
renderer.material.mainTexture = totalpictures[counter]; //
}
}
if(counter >= totalpictures.length){
//if(counter >= totalpictures.GetRange){
Debug.Log("exceeding material length");
if(loop == true){
counter = 0; // goes back to first frame
}
}
}
}
$$anonymous$$ay be a long shot, but have you tried firing a single Plane out of the particle system then using a Sprite Animation texture sheet to simulate video?
Haven't tried that or even thought of it. So what you're trying to say is that if I tried to fire planes with the textures on them with animation sheets? I don't even know how to do that or know where to start.
Shuriken Particle system has Sprite sheet animation, which basically chucks out each tile of a texture each time period. I'm not sure what the texture size limit is though, or what res you can achieve. Basically you need to set Rate to 0 and set Burst Particles to 1 for an individual paticle. $$anonymous$$ake it have 0 velocity and an initial size of your choice.
Wow. Your code is so simple yet it works like a charm but i don't code in javascript but in C#. Well anyway thanks!
Answer by Eric5h5 · Oct 05, 2013 at 04:24 PM
I like how the javascript works but I modified it to C# codes but it isn't as fluid as yours.
public Texture2D[] frames;
int theTime;
public int framesPerSecond = 10;
void Update (){
theTime = $$anonymous$$athf.RoundToInt(Time.time);
int index = theTime * framesPerSecond;
index = index % frames.Length;
renderer.material.mainTexture = frames[index];
}
I needed a C# version of it but this is as close as it gets but it isn't as smooth than the javascript version. Is there like a way to implicitly or explicitly convert int to float? (for the renderer.material line)
You can cast an int to a float like this:
int myInt = 1;
float myFloat = (float)myInt;
Also, if you have a constant value, you can declare it as a float by postfixing the letter F
. This is useful because as long as one value in a calculation is a float, the entire calculation will be calculated with floats. For example:
int i = 5;
float f = 5 * i/2f;
Will give you 12.5, while:
int i = 5;
float f = 5 * i/2;
Will give you 10. The way to think about it is that there is no basic operation that operates on ints and floats at the same time. The operation 1/2
uses the simpler type int, as it wasn't specified otherwise, so 1 is an int, 2 is an int, and it operates using integer division, giving the value 0 (since it can only return an int). However, the operation 1/2f
does not operate on an int and a float, ins$$anonymous$$d it implicitly casts the int to a float, because it has to cast in one direction, and floats cannot be implicitly cast to ints. Therefore, it converts the 1 into the float 1.0f, and runs the operation 1.0f/2.0f
, which is floating point division, returning the expected value of 0.5f
. Note that with floating point division, 4f/2
will still be floating point division, and will return the value 2f
, with type float, not type int.
A straight Unityscript to C# conversion is:
public Texture2D[] frames;
public float framesPerSecond = 10.0f;
void Update () {
int index = (int)(Time.time * framesPerSecond);
index = index % frames.Length;
renderer.material.mainTexture = frames[index];
}
Don't make global variables unless you absolutely need to.