How to change sprite.Texture of a sprite?

Right now during code, I take a texture in the asset folder, make a new texture (duplicate it), and then edit the duplicate to be different.

I assume that it is changed (although I can’t check, the code seems correct).

However, when I go to update the sprite’s texture, it gives me the error:

I cannot find any other way to change the Sprite’s texture in the API.

I wanted a simple way to do this, because the sprite’s texture is actually a spritesheet, with tons of individual sprites within it.
All I’m trying to do is change the color of the pixels. Everything else stays exactly the same.

I tried something to get this to work, and it seems to work well in copying the texture2D to a new texture2D (that way if I change the new one, it DOESNT change the old one too.)

Now, it also doesn’t seem to dye the character at all.

What does NOT work, is applying this texture to a new sprite.

It just shows an empty grey box and an empty Sprite, but the Texture2D is correct.

Not sure what I was thinking. It is unnecessary to create the iamge and then edit it.

So I went ahead and changed the pixel colors while it was copying the image in CopyTexture2D.

Still not sure why it refused to edit them, but worked flawlessly. I imagine it has something to do with IsReadable, and how…apparently…Unity can’t access textures in VRAM, and has no way of transfering them to RAM to be edited. That explains why a texture2d can be created on the fly, but not edited? I am guessing once you .Apply(), it is done with.

I still have no idea why my sprite is not updating… :frowning:

So here it is, cleaned up.

Now it…

  1. Successfully Copies Sprite’s Texture2D to a new Texture2D.
  2. Edits the Pixels and changes their Color. Sprite is correctly colored!
  3. Displays a Grey Rectangle, with Sprite as Empty. Sprite is nowhere to be found.
	public Texture2D CopyTexture2D(Texture2D copiedTexture)
	{
		Texture2D texture = new Texture2D(copiedTexture.width, copiedTexture.height);
		texture.filterMode = FilterMode.Point;
		texture.wrapMode = TextureWrapMode.Clamp;

		int y = 0;
		while (y < texture.height)
		{
			int x = 0;
			while (x < texture.width)
			{
				if(copiedTexture.GetPixel(x,y) == new Color(0,255,0))
				{
					texture.SetPixel(x, y, Color.red);
				}
				else
				{
				texture.SetPixel(x, y, copiedTexture.GetPixel(x,y));
				}
				++x;
			}
			++y;
		}
		texture.Apply();
	

		return texture;
	}
	
	public void DyeCharacter()
	{
		characterTexture2D = CopyTexture2D(gameObject.GetComponent<SpriteRenderer> ().sprite.texture);
	
		SpriteRenderer sr = GetComponent<SpriteRenderer>();
		sr.sprite = Sprite.Create (characterTexture2D, sr.sprite.rect, new Vector2(0,0),100);

	}
1 Like

On closer inspection, when I click on the Sprite icon and check the newly created sprite, it works! It displays the correct image, and image name.

So I have absolutely no idea why the sprite is not rendering. Is it the material?

1 Like

Here was the solution:

		sr.material.mainTexture = characterTexture2D;
		sr.material.shader = Shader.Find ("Sprites/Transparent Unlit");

As I suspected, it was exactly that: the material.

Unity could really use more additional features, which are kind of common sense to anyone using the engine.

There is no easy way to access the default materials, such as something like

Renderer.material = new Material(“Diffuse”);

I also could not find ANYWHERE in documentation that I had to assign the Sprite material with both the new texture AND the new shader. This is counter-intuitive to the way the Sprite material interfaces with the user.

For reference, here is the complete solution which does it:

http://forum.unity3d.com/threads/223030-Best-Easiest-way-to-change-color-of-certain-pixels-in-a-single-Sprite?p=1489422&viewfull=1#post1489422

2 Likes

If you are just trying to get a ordinary sprite into a material, just put .texture at the end of the sprite
_iconMaterialInstance.SetTexture(“_Background”, action.IconBackground.texture);