using UnityEngine; #if UNITY_EDITOR using UnityEditor; #endif using System.Collections; [ExecuteInEditMode] public class TextureAnimator : MonoBehaviour { int numberToAnimate; int lastNum; public bool incrementListLength = false; public bool decrementListLength = false; public Material[] textureList; public bool[] enable_animation; public float[] fps; public int[] frames; public int[] columns; public int[] rows; //private static int largestNum; Maybe use this to record the largest state of the arrays in history, //so resizing back to a bigger size would remember entries. For now, no. // Use this for initialization void Start () { //Reset numberToAnimate for the correct value when it changes to 0 upon script //restart or recompilation if(textureList != null) { if(numberToAnimate < textureList.Length) { numberToAnimate = textureList.Length; lastNum = numberToAnimate; } } } // Update is called once per frame void Update() { //Using checkboxes as buttons to increase/decrease the list length //This is to avoid accidental clearing of the animation list if(incrementListLength) { numberToAnimate++; incrementListLength = false; } else if(decrementListLength) { numberToAnimate--; decrementListLength = false; } //If the list length changed, update all arrays to reflect that if(lastNum != numberToAnimate) { //Material[] m = textureList; System.Array.Resize(ref textureList,numberToAnimate); //bool[] e = enable_animation; System.Array.Resize(ref enable_animation,numberToAnimate); System.Array.Resize(ref fps,numberToAnimate); System.Array.Resize(ref frames,numberToAnimate); System.Array.Resize(ref columns,numberToAnimate); System.Array.Resize(ref rows,numberToAnimate); //If the list length grew, set default values to the new array elements //This avoids errors in the script execution if(numberToAnimate > lastNum) { if(gameObject.GetComponent(typeof(Renderer)) != null) textureList[lastNum] = GetComponent().sharedMaterial; #if UNITY_EDITOR else textureList[lastNum] = (Material)AssetDatabase.LoadAssetAtPath("Assets/_Materials/tile_Lab_big.mat", typeof(Material)); #endif enable_animation[lastNum] = true; fps[lastNum] = 10; frames[lastNum] = 1; columns[lastNum] = 1; rows[lastNum] = 1; } //Update lastNum to continue comparing it to numberToAnimate lastNum = numberToAnimate; } //Iterate through all existing textures to be animated, and change their current //frame as necessary for(int i = 0; i < numberToAnimate; i++) { if(enable_animation[i]) { int index = (int)Mathf.Floor(Time.time * fps[i]); index %= frames[i]; //Debug.Log("Index update -- index is now: " + index + "."); Vector2 size = new Vector2(1.0f / (float)columns[i], 1.0f / (float)rows[i]); int uIndex = index % columns[i]; //No need to round -- modulus always returns an integer int vIndex = (int)Mathf.Floor((float)index / (float)columns[i]); //Position was messing up because this was rounding instead of flooring //E.g., index 2 should return vIndex of 0. //Round: 2 (index)/4 (columns) or 0.5 and you get 1, //Floor: 2/4 or 0.5 and you get 0. Vector2 offset = new Vector2((float)uIndex * size.x, Mathf.Repeat(1f - size.y - (float)vIndex * size.y,1f)); textureList[i].SetTextureOffset("_MainTex", offset); textureList[i].SetTextureScale ("_MainTex", size); } } } }