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 * 0.25f, animationInfo.Sheet.height / animationInfo.Frames, 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 = ((int)Dir * spriteSize.x) / animationInfo.Sheet.width;
float uEnd = uStart + spriteSize.x / animationInfo.Sheet.width;
float vStart = (Frame * 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 Direction Dir = Direction.DownRight;
public int Frame = 0;
// Update is called once per frame
void Update () {
}
}