- Home /
PackTextures Horizontally? (1 Row) or Alternative Method
It makes me very upset that Unity's Texture2D.PackTextures built-in function is not flexible enough to allow me to pack my textures horizontally.
I am trying to dynamically create a strip of textures for a wheel-like UI component, and the end result I want is something like this:
(Each color represents a diff texture)
The amount of textures, and the textures themselves are dynamic, therefore everything needs to be done in run-time.
I understand that this unfortunately cannot be achieved w/ packTextures (or can it?), so I'm looking for an alternative way to achieve the same result.
Answer by MStoneC · Sep 25, 2014 at 09:37 AM
I ended up figuring out a work around to achieve the result that I wanted. If anyone's every trying to do something similar w/ dynamic textures in general, this can be achieved by using a combination of Texture2D.ReadPixels and RenderTexture.
Doing the ReadPixels without the RenderTexture might work in some scenarios, but in my case where the texture's length was dynamic, and could've potentially been super long. The non-RenderTexture method would cap your resulting image's width by whatever the current screen size is. Using RenderTexture, you can specify a width that's larger than your screen's bounds, and then use Texture2D.ReadPixels to get the correct crop for your texture.
Notes that might help:
If you're using ReadPixels without Render Texture, the x: 0, and y:0 positions for ReadPixels (as documented) starts from the bottom left of your screen. However, if RenderTexture is active on the Camera that you're reading pixels from, it uses the upper left corner of your camera's viewport . Took some trial and error to figure out exactly how it all works, but the result was more than worth it in the end.
Snippet (UnityScript / JS):
var camera:Camera = {Your Camera}
var mWidth:float = {Your texture width in pixels}
var mHeight:float = {Your texture height in pixels}
var mContainer:GameObject = {Your target object(s) container}
//Set Camera's Ortho Size to be pixel based
camera.orthographicSize = Screen.height / 2f / 100f;
//Position Your Object's Container on the top left of the cam's view port
nPos = new Vector3(-((camera.pixelWidth/100)/2) - (((((Mathf.Max(camera.pixelWidth, mWidth)) - camera.pixelWidth)/100)/2), ((camera.pixelHeight/100)/2), 0);
mContainer.transform.position = nPos;
var rt:RenderTexture = new RenderTexture(Mathf.Max(mWidth, camera.pixelWidth), camera.pixelHeight, 24);
camera.targetTexture = rt;
var screenShot:Texture2D = new Texture2D(mWidth, mHeight);
camera.Render();
RenderTexture.active = rt;
screenShot.ReadPixels(new Rect(0, 0, mWidth, mHeight), 0, 0);
screenShot.Apply();
camera.targetTexture = null;
RenderTexture.active = null;
Hope this helps someone.
Side Note: If for some reason it isn't feasible for you to move your object to the upper left corner, consider just editing the start x/y values on ReadPixels instead.