I have the following code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TextureScript : MonoBehaviour
{
Texture2D texture;
// Start is called before the first frame update
void Start()
{
texture = new Texture2D(256,256, TextureFormat.RGB24, true);
var rectTransform = transform.GetComponent<RectTransform>();
rectTransform.sizeDelta = new Vector2(texture.width, texture.height);
int pixelCount = texture.width * texture.height;
Queue<Color> queue = new Queue<Color>();
for(int i = 0; i < pixelCount; i++)
{
queue.Enqueue(new Color(255,0,0));
}
Color[] colorArray = queue.ToArray();
texture.SetPixelData(colorArray, 0, 0);
texture.filterMode = FilterMode.Point;
texture.Apply(updateMipmaps: false);
GetComponent<RawImage>().material.mainTexture = texture;
}
// Update is called once per frame
void Update()
{
}
}
Which produces this:
I am unsure as to what could be producing it. Previously I was using a byte array for tests which worked, but my work now requires a queue, and to then convert this queue into an array (which I have done using .ToArray()).
I also used RGBA32 rather than RGB24 with varying alpha values of 255, 128, 1, & 0; however, this produced a nearly see-through image each time.
Thank-you for your help.
Queue
instead of simply an array?SetPixelData
instead of simply SetPixels
?I would simply do e.g.
//var pixels = texture.GetPixels();
// or even simply
var pixels = new Color[texture.width * texture.height];
for(var i = 0; i < pixels.Length; i++)
{
pixels[i] = color.Red;
}
texture.SetPixels(pixels);
texture.Apply();
SetPixelData
is rather
useful if you want to load compressed or other non-color texture format data into a texture.
What happens in your case is: Color
has a byte
size of 4 float (=16 byte
) since it also has an alpha value! Your texture is using RGB24
and therefore only expecting 3 bytes (=24 bit) per pixel.
So in case if you really want to stick to that (might be faster - or not ^^) you would rather have to do e.g.
var pixels = new byte[texture.width * texture.height * 3];
for(var i = 0; i < pixels.Length; i+=3)
{
pixels[i] = 255; // R
pixels[i+1] = 0; // G
pixels[i+2] = 0; // B
}
texture.SetPixelData(pixels, 0, 0);
texture.Apply();
also regarding
new Color(255,0,0)
note that Color
takes float arguments from 0
to 1
. If you are looking for a byte based input rather go for Color32
and SetPixels32
Further note that RawImage
is actually quite expensive - you could stick to an Image
component and simply create a Sprite
from your Texture2D
GetComponent<Image>().sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);