- Home /
Applying Textures from atlas?
Im trying to apply a simple 2d texture to a cube from my atlas script.
#pragma strict
// Source textures.
var atlasTextures: Texture2D[];
// Rectangles for individual atlas textures.
var rects: Rect[];
function Start () {
// Pack the individual textures into the smallest possible space,
// while leaving a two pixel gap between their edges.
var atlas = new Texture2D(8192, 8192);
rects = atlas.PackTextures(atlasTextures, 2, 8192);
print(atlasTextures[0]);
// atlasTextures[0] = GameObject.Find("Cube1");
var temp = transform.Find("Cube1");
atlasTextures[0] = temp.renderer.material.mainTexture;
}
this is what i got...I think the last 2 lines need to change.. they are throwing nullreference exceptions. Any direction would be greatly appreciated. Thanks!
There was no need to bump after half an hour. As for your question - try using some Debug.Log statements to find out which of those is returning null. To throw a NullReferenceException, it has to be at least one level in, so it's not atlasTextures[0] that is null, nor is it mainTexture. It could be the atlasTextures array itself, but I'm assu$$anonymous$$g you're setting that in the inspector. It could also be temp, temp.renderer or temp.renderer.material. Try adding these lines to your code:
Debug.Log(atlasTextures);
Debug.Log(temp);
Debug.Log(temp.renderer);
Debug.Log(temp.renderer.material);
This should deter$$anonymous$$e which of these is null, which will help to discover the cause of the problem.
Answer by aldonaletto · Sep 30, 2013 at 01:38 AM
transform.Find only searches in the object's children - if "Cube1" isn't a child of the object this script is attached to, temp will be set to null and generate Null Reference Exception. Use GameObject.Find instead:
...
var temp = GameObject.Find("Cube1");
atlasTextures[0] = temp.renderer.material.mainTexture;
}
EDITED: PackTextures merges the textures passed in the array into a single texture and returns an array of Rects that shows the location of each texture in the atlas. In order to use the packed textures, assign the atlas to the mainTexture and define the texture offset and scale according to the corresponding rect. If you want to use the packed version of atlasTextures[2], for instance, do the following:
...
var temp = GameObject.Find("Cube1");
temp.renderer.material.mainTexture = atlas;
temp.renderer.material.mainTextureOffset = Vector2(rects[2].x, rects[2].y);
temp.renderer.material.mainTextureScale = Vector2(rects[2].width, rects[2].height);
That fixed the nullrefexception but now im getting another error that says invaildCastException... Sorry for the trouble. its just ive never seen these types of errors.
What it is doing though is creating a instance material but not applying the texture to it...The material on Cube1 says Default-Diffuse(Instance)
Never$$anonymous$$d i fixed it! Heres the code i used to apply textures to a model from an atlas! Thanks @aldonaletto for your direction.
#pragma strict
// Source textures.
var atlasTextures: Texture2D[];
// Rectangles for individual atlas textures.
var rects: Rect[];
function Start () {
// Pack the individual textures into the smallest possible space,
// while leaving a two pixel gap between their edges.
var atlas = new Texture2D(8192, 8192);
rects = atlas.PackTextures(atlasTextures, 2, 8192);
var temp = GameObject.Find("Cube1");
temp.renderer.material.mainTexture = atlasTextures[0];
}
But notice that you're using the original texture, not the one packed in the atlas. In order to use the atlas texture, you must assign atlas to the texture and set its offset and scale according to the rect returned by PackTextures. Take a look at my answer: I edited it and added the code to effectively use the atlas.