using System; using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; [Serializable] public struct AnimationInfo { public Texture2D Sheet; public int Frames; public Vector2 Offset; public string Name; } [SelectionBase] public class AnimationHandler : MonoBehaviour { public float PixelScale = 0.1f; public AnimationInfo[] Animations; public GameObject Target; private Material mat; private Mesh mesh; private AnimationInfo animationInfo; private Vector3 spriteSize = new Vector2(); // Use this for initialization void Start () { MeshFilter mf = Target.GetComponentInChildren<MeshFilter>(); MeshRenderer rend = Target.GetComponentInChildren<MeshRenderer>(); mat = rend.material; animationInfo = Animations[0]; UpdateMat(); mesh = new Mesh(); mesh.SetVertices(verts); mesh.SetUVs(0, uvs); mesh.SetTriangles(new int[] { 0, 1, 2, 0, 2, 3 }, 0); UpdateMesh(); mf.sharedMesh = mesh; } private void UpdateMat() { spriteSize = new Vector3(animationInfo.Sheet.width / animationInfo.Frames, animationInfo.Sheet.height * 0.25f, 1); mat.SetTexture("_MainTex", animationInfo.Sheet); } private List<Vector3> verts = new List<Vector3> { new Vector3(1, 1, 0), new Vector3(1, -1, 0), new Vector3(-1, -1, 0), new Vector3(-1, 1, 0) }; private List<Vector2> uvs = new List<Vector2> { new Vector2(1, 1), new Vector2(1, 0), new Vector2(0, 0), new Vector2(0, 1) }; private void UpdateMesh() { Vector3 offset = new Vector3(animationInfo.Offset.x, spriteSize.y - animationInfo.Offset.y, 0); Vector3 spriteSizeMult = new Vector3(spriteSize.x, spriteSize.y); verts[0] = (Vector3.Scale(new Vector3(1, 1, 0), spriteSize) - offset) * PixelScale; verts[1] = (Vector3.Scale(new Vector3(1, 0, 0), spriteSize) - offset) * PixelScale; verts[2] = (Vector3.Scale(new Vector3(0, 0, 0), spriteSize) - offset) * PixelScale; verts[3] = (Vector3.Scale(new Vector3(0, 1, 0), spriteSize) - offset) * PixelScale; mesh.SetVertices(verts); //float uStart = / animationInfo.Sheet.width; //float uEnd = uStart + spriteSize.x / animationInfo.Sheet.width; // //float vStart = / animationInfo.Sheet.height; //float vEnd = vStart + spriteSize.y / animationInfo.Sheet.height; //float uStart = ((animationInfo.Frames - Frame - 1) * spriteSize.x) / animationInfo.Sheet.width; float uStart = (Frame * spriteSize.x) / animationInfo.Sheet.width; float uEnd = uStart + spriteSize.x / animationInfo.Sheet.width; //float vStart = ((int)Dir * spriteSize.y) / animationInfo.Sheet.height; float vStart = ((3 - (int)Dir) * spriteSize.y) / animationInfo.Sheet.height; float vEnd = vStart + spriteSize.y / animationInfo.Sheet.height; uvs[0] = new Vector3(uEnd, vEnd); uvs[1] = new Vector3(uEnd, vStart); uvs[2] = new Vector3(uStart, vStart); uvs[3] = new Vector3(uStart, vEnd); mesh.SetUVs(0, uvs); mesh.RecalculateNormals(); mesh.RecalculateBounds(); } public enum Direction { DownRight = 0, UpRight, UpLeft, DownLeft } public void SetState(string animationName, Direction dir, int frame) { bool changed = false; if (animationName != animationInfo.Name) { changed = true; animationInfo = Animations.First(a => a.Name == animationName); UpdateMat(); } if (this.Dir != dir) { changed = true; this.Dir = dir; } if (this.Frame != frame) { changed = true; this.Frame = frame; } if (changed) { UpdateMesh(); } } public void SetDir(Direction dir) { if (this.Dir != dir) { this.Dir = dir; UpdateMesh(); } } public void SetFrame(int frame) { if (this.Frame != frame) { this.Frame = frame; UpdateMesh(); } } public Direction Dir = Direction.DownRight; public int Frame = 0; // Update is called once per frame void Update () { } }