В стандартном случае (я так всё время раньше делал, такой пример есть на википедии) работа ведется с renderer.material.offset\scale.
Минусом такого подходом является то, что при изменении смещения текстуры на одном объекте создается копия материала в памяти и они не бачатся.
Тест первых двух способов:
200 квадов (2 треугольника, 4 вершины), dynamic batching включен
1. "material offset"
результаты: 330 fps, 200 draw calls, 0 batched
2. "swap meshes" (при запуске композиции на каждый кадр анимации создается копия меша, кадр переключается через MeshFilter.mesh = frames[index], материал на всех квадах один и тот же)
результаты: 615 fps, 1 draw calls, 200 batched
Вывод: material.offset - говно
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
public class MatOffsetAnimScript : MonoBehaviour
{
//vars for the whole sheet
int colCount = 4;
int rowCount = 4;
//vars for animation
int rowNumber = 0; //Zero Indexed
int colNumber = 0; //Zero Indexed
int totalCells = 4;
public int fps = 10;
Vector2 offset; //Maybe this should be a private var
MeshFilter mf;
void Start()
{
mf = gameObject.GetComponent<MeshFilter>();
}
//Update
void Update () { SetSpriteAnimation(colCount,rowCount,rowNumber,colNumber,totalCells,fps); }
//SetSpriteAnimation
void SetSpriteAnimation(int colCount,int rowCount,int rowNumber,int colNumber, int totalCells, int fps)
{
// Calculate index
int index = (int)Time.time * fps;
// Repeat when exhausting all cells
index = index % totalCells;
// Size of every cell
Vector2 size = new Vector2 (1.0f / colCount, 1.0f / rowCount);
// split into horizontal and vertical index
int uIndex = index % colCount;
int vIndex = index / colCount;
// build offset
// v coordinate is the bottom of the image in opengl so we need to invert.
////Vector2 offset = new Vector2 ((uIndex+colNumber) * size.x, (1.0f - size.y) - (vIndex+rowNumber) * size.y);
//type1
//renderer.material.SetTextureOffset ("_MainTex", offset);
////renderer.material.SetTextureScale ("_MainTex", size);
mf.mesh = FrameHolder.singleton.frames[uIndex];
}
}
using UnityEngine;
using System.Collections;
public class FrameHolder : MonoBehaviour
{
[HideInInspector]
public Mesh[] frames;
public Mesh source_mesh;
public static FrameHolder singleton;
void Awake()
{
singleton = this;
int n=4;
frames = new Mesh[n];
float step = 1f/n;
for(int i=0; i<n; i++)
{
frames[i] = (Mesh)Instantiate(source_mesh);
frames[i].uv = new Vector2[] { new Vector2(i * step + 0, 0), new Vector2(i * step + step, 0), new Vector2(i * step + 0, step), new Vector2(i * step + step, step) };
}
}
}
using System.Collections;
public class MatOffsetAnimScript : MonoBehaviour
{
//vars for the whole sheet
int colCount = 4;
int rowCount = 4;
//vars for animation
int rowNumber = 0; //Zero Indexed
int colNumber = 0; //Zero Indexed
int totalCells = 4;
public int fps = 10;
Vector2 offset; //Maybe this should be a private var
MeshFilter mf;
void Start()
{
mf = gameObject.GetComponent<MeshFilter>();
}
//Update
void Update () { SetSpriteAnimation(colCount,rowCount,rowNumber,colNumber,totalCells,fps); }
//SetSpriteAnimation
void SetSpriteAnimation(int colCount,int rowCount,int rowNumber,int colNumber, int totalCells, int fps)
{
// Calculate index
int index = (int)Time.time * fps;
// Repeat when exhausting all cells
index = index % totalCells;
// Size of every cell
Vector2 size = new Vector2 (1.0f / colCount, 1.0f / rowCount);
// split into horizontal and vertical index
int uIndex = index % colCount;
int vIndex = index / colCount;
// build offset
// v coordinate is the bottom of the image in opengl so we need to invert.
////Vector2 offset = new Vector2 ((uIndex+colNumber) * size.x, (1.0f - size.y) - (vIndex+rowNumber) * size.y);
//type1
//renderer.material.SetTextureOffset ("_MainTex", offset);
////renderer.material.SetTextureScale ("_MainTex", size);
mf.mesh = FrameHolder.singleton.frames[uIndex];
}
}
using UnityEngine;
using System.Collections;
public class FrameHolder : MonoBehaviour
{
[HideInInspector]
public Mesh[] frames;
public Mesh source_mesh;
public static FrameHolder singleton;
void Awake()
{
singleton = this;
int n=4;
frames = new Mesh[n];
float step = 1f/n;
for(int i=0; i<n; i++)
{
frames[i] = (Mesh)Instantiate(source_mesh);
frames[i].uv = new Vector2[] { new Vector2(i * step + 0, 0), new Vector2(i * step + step, 0), new Vector2(i * step + 0, step), new Vector2(i * step + step, step) };
}
}
}