I’ve run into a strange issue in an iPhone project, but it raises a more general Unity question…
I have a texture on the front face of a cube in a 2D game. In order to simulate animation, I’ve created the texture as a series of frames, like a filmstrip. The texture horizontal tiling is set to 1/20. The first 10 frames are for one animation and the next 10 are for another. I’m looping the first 10 frames as follows (the initial value of my iFrame variable = 1):
void FixedUpdate ()
{
float dx = 1024.0f / 20.0f;
float ofs = (iFrame - 1) * dx;
// Move texture to the left.
renderer.material.mainTextureOffset = new Vector2(-ofs, 0f);
// Limit the frame range to 1-10.
iFrame = Mathf.Repeat(Mathf.Round(Time.time * 4), 10);
if (iFrame == 0)
iFrame = 1;
}
But I’m finding that I get to the end of the texture too quickly. Despite the fact that iFrame <= 10, I see frames 1-20 on screen. So I’m wondering if Unity is doing some kind of optimization that causes texture frames to be skipped. For example, if two adjacent frames are identical, maybe Unity is removing one of them and making my texture shorter. I don’t think my code is wrong, but I’m open to suggestions. Any ideas?
I’m not using PackTextures, and as far as I know there are no relevant quality settings for iPhone. When I query mainTexture.width, it is 1024 as expected. Yet even when the texture is shifted by only about 200, I’m getting images from the end of the texture. Could there be scaling or some other optimization going on?
OK, I have something figured out. If I change the statement:
float dx = 1024.0f / 20.0f;
to:
float dx = 1.0f / 20.0f;
It switches frames correctly. It is as if the width of the texture is actually being normalized to 1 and not 1024 as in the inspector. Is this expected behavior and is my question just a result of not understanding how texture coordinates work?
Yes, that’s correct. Texture coordinates are always in the range 0 to 1, where 0 is the left/bottom and 1 is the right/top. So if the texture coordinates are 2,2 at one corner of a quad and 0,0 at the other corner, the texture will tile twice in each direction over that quad (i.e. it will be drawn four times). Good work, I should have spotted that in the first place
So, in other words, 1/20 means 1/20th of the texture dimension, or 51.2 pixels. It’s usually best to use a power of two, like 1/16 or 1/32, in order to avoid potential problems with colors bleeding into eachother.
To clarify, texture coordinates are not always in the range 0 to 1. What I meant to say was that the range 0 to 1 always maps the entire texture, regardless of the texture’s size.
Also, using power-of-two frame sizes won’t completely eliminate color bleeding problems. You may need to put a transparent border around each frame. Wow, I need to stop hitting submit so fast