- Home /
Texture offset causes stretching
Managed to figure out the answer, but in the chance this happened to anyone else, I'll leave it here anyway for reference.
The short of it: When offsetting textures to animate through a spritesheet using a javascript, the texture offsets, but then only takes the top 1 pixel and then stretches it down the entire offset.
So, on a 3x2 sheet it is correctly offsetting the X to 1/3, but then on the Y it is dragging the same 1 pixel down all the way vertically.
Now this problem seems to only be happening with a specific script, however that script has been working. Then, twice now on different occasions and caused by different errors, it seems to just break project-wide. I can take the very same script, put it in a new project, and have it work fine.
This is happening in Unity 4.3.0f, and has happened in three different projects (two of mine, one of a team member's).
A different offsetting script that still works but I can't really control like I need to is this (which was found online in referencer material):
var uvAnimationTileX = 24; //Here you can place the number of columns of your sheet.
//The above sheet has 24
var uvAnimationTileY = 1; //Here you can place the number of rows of your sheet.
//The above sheet has 1
var framesPerSecond = 10.0;
function Start () {
}
function Update () {
// Calculate index
var index : int = Time.time * framesPerSecond;
//index = Time * 10
// repeat when exhausting all frames
index = index % (uvAnimationTileX * uvAnimationTileY);
//index = index % 24 * 1
// Size of every tile
var size = Vector2 (1.0 / uvAnimationTileX, 1.0 / uvAnimationTileY);
//Size = 1.0 / 24, 1.0 / 1
// split into horizontal and vertical index
var uIndex = index % uvAnimationTileX;
var vIndex = index / uvAnimationTileX;
// build offset
// v coordinate is the bottom of the image in opengl so we need to invert.
var offset = Vector2 (uIndex * size.x, 1.0 - size.y - vIndex * size.y);
renderer.material.SetTextureOffset ("_MainTex", offset);
renderer.material.SetTextureScale ("_MainTex", size);
}
Now, the script I'm using has a function SpriteLayout() that is called at the start (or called when the user wants) to take the X and Y variables assigned by the user and basically cut the spritesheet's offset coordinates up into an array so that each frame can be called easily. That function is where the problem seems to be starting once the project 'corrupts' as I'll put it, and so I'll link that part (as well as all the variables). As a heads up, I did accidentally name the X and Y variables incorrectly in terms of making sense, so understand that rowsX IS the X, but obviously should be named columnsX. I just made a derp when I wrote it, so my apologies.
My script that is having problems:
The variables:
//Frames per second
var framesPerSecond : float = 1.0;
//Size of the spritesheet in Rows and Columns
var rowsX : int = 0;
var columnsY : int = 0;
//Array where coordinates of frames in the spritesheet are stored. Use this to set the amount of frames
var frameCoords : Vector2[];
//Used to assign the actual offset to the material
private var offset : Vector2;
//Size of the frames in the spritesheet
private var frameSize : Vector2;
//Used to calculate sprite locations when the spritesheet is initialized via SpriteLayout function
private var xSize : float = 0.0;
private var ySize : float = 0.0;
private var spriteLoc : Vector2;
//Used to track the current row and column during initialization
private var rowTrack : int = 0;
private var columnTrack : int = 0;
@HideInInspector var currentFrame : int = 0;
//Start and finish frames
private var aniStart : int = 0;
private var aniEnd : int = 0;
//Bools to determine the current function, IE aniamting start to finish, animating a loop, etc.
private var aniTo : boolean = false;
private var aniLoop : boolean = false;
@HideInInspector var frameLerp : float = 0.0;
The initializing function that creates the offset and array:
//Initializes the spritesheet
function SpriteLayout(){
rowTrack = 0;
columnTrack = 0;
xSize = 1.0 / rowsX;
ySize = 1.0 / columnsY;
frameSize = Vector2(xSize, ySize);
spriteLoc = Vector2(0 - xSize, 0 - ySize);
for(var i : int = 0; i < frameCoords.Length; i++){
if(rowTrack == rowsX && columnTrack < columnsY){
rowTrack = 0;
columnTrack += 1;
spriteLoc.x = 0 - xSize;
spriteLoc.y -= ySize;
if(columnTrack == columnsY){
spriteLoc.y = 0;
}
}
rowTrack += 1;
spriteLoc.x += xSize;
frameCoords[i] = spriteLoc;
}
offset = frameCoords[0];
renderer.material.SetTextureOffset ("_MainTex", offset);
renderer.material.SetTextureScale ("_MainTex", frameSize);
}
Here is a screenshot showing 1. The materials set up in the scene, with the working scripted object on the left and the broken one on the right. 2. Those objects both when play is hit, but without having run the SpriteLayout() function on the right yet. 3. When SpriteLayout() has been run on the right object (obviously in a broken project), correctly offsetting the X but then stretching down the Y pixels.
I'm completely willing to accept I may have screwed something up, but it doesn't make sense to me that the script works, then stops working when the editor throws an error completely unrelated to the script, or the material in use, or anything relating to the animation. The two different times I had it break were on an error where I'd taken the renderer off an object but left a script on it trying to access it, and the other was when I commented back in code for getting touch input but ran the game on the pc and had it throw an error about the touch index. After each of those, both in seperate projects, it caused the offsets of this script to break permanently in those projects.
This is a pretty big stinker for me, since it effectively breaks the code I need for animating sprites in a project. If it's something with Unity, I'd like to at least know, but obviously if it's something I'm doing wrong then any pointers in the right direction of how to fix it (and avoid whatever triggers the problem) would be extremely appreciated.
Obviously, thank you anyone who takes the time to read this and reply.
Answer by Ria Ayo · Mar 12, 2014 at 07:55 PM
Well in the typical fashion for me, once I actually go look for help I finally come across what seems to be the problem.
My Y offset is being made a negative value rather than a positive like the other script. So, when making it positive, the texture works again. What I guess I need to figure out and understand is why it's started doing this when it didn't before? Or did a negative offset use to work but a Unity update changed that? I will just have to play around with it and see, I suppose, but it looks like that was my issue.
I figured out the exact problem is that:
spriteLoc = Vector2(0 - xSize, 0 - ySize);
needs to be:
spriteLoc = Vector2(0 - xSize, 1 - ySize);
My only guess is that using negative values use to work, and an update changed that? I can't figure out otherwise why the way this use to initialize suddenly stopped working.
I'll go ahead and leave this up in the off chance some other idiot like me runs into the same dumb problem.
Your answer
![](https://koobas.hobune.stream/wayback/20220613140105im_/https://answers.unity.com/themes/thub/images/avi.jpg)