Change sprites colours individualy ( flashing like mario with the star )

I’m making a retro 8 bit plataformer, and I want to know how can I change the pallete of my sprites, similar to the flashing mario, without using other sprite sheets.

This gif from shovel knight is exactly what i want:

these too:

I dont want to just mess with the color of the material, that tints every color, I’m looking for a way to replace colors individually. ( for making other effects too, like a boss coming out of the dark with the colors gradualy appearing )

I had a go at this, not able to test currently, could fail spectacularly!

Sorry if a bit hard to read, I added some comments. :slight_smile:

Just feed it a Texture2D image & associated Rect somehow (there is probably a better way of handling this, that I fail to find right now)

using UnityEngine;
using System.Collections.Generic;

public class ColorChanger : MonoBehaviour
	public Texture2D SourceTex;
	public Rect SourceRect;

	private int x;
	private int y;
	private int width;
	private int height;

	private Color[] pixels;
	private List<Color> colorList;
	private List<Color> backupColorList;

	void Start()
		// Get Rect dimensions
		x = Mathf.FloorToInt( SourceRect.x );
		y = Mathf.FloorToInt( SourceRect.x );
		width = Mathf.FloorToInt( SourceRect.width );
		height = Mathf.FloorToInt( SourceRect.height );

		// Read image into pixel array
		pixels = SourceTex.GetPixels( x, y, width, height );

	// Make a list of all used colors in the image.
	List<Color> GetColorList()
		var cList = new List<Color>();

		foreach( var pixel in pixels )
			if( cList.Count == 0 )
				cList.Add( pixel );
				Debug.Log( "Added first color: " + pixel );
				var found = false;
				foreach( Color c in cList )
					if( c == pixel )
						found = true;
				if( !found )
					cList.Add( pixel );
					Debug.Log( "Added color " + cList.Count + ": " + pixel );
		return cList;

	// Change one color into another.
	void ChangeColor( Color oldC, Color newC )
		for( var i = 0; i < pixels.Length; i++ )
			if( pixels *== oldC )*
  •  	{*

_ pixels = newC;_
* }*
* }*
* SourceTex.SetPixels( x, y, width, height, pixels, 0 );*
* SourceTex.Apply();*
* }*

* // or with float’s*
* void ChangeColorF( float oldR, float oldG, float oldB, float oldA, float newR, float newG, float newB, float newA )*
* {*
* for( var i = 0; i < pixels.Length; i++ )*
* {*
_ if( pixels == new Color( oldR, oldG, oldB, oldA ) )
* {
pixels = new Color( newR, newG, newB, newA );
SourceTex.SetPixels( x, y, width, height, pixels, 0 );
Then you could do stuff like:
// Generate a list of unique colors in the image.*

colorList = GetColorList();_

// Backup original colors and randomize.
backupColorList = colorList;
for( var i = 0; i < colorList.Count; i++ )
_ colorList = new Color( Random.Range( 0f, 1f ), Random.Range( 0f, 1f ), Random.Range( 0f, 1f ), 1f );
ChangeColor( backupColorList, colorList );

// Change all Black pixels to White using float’s
ChangeColorF( 0f, 0f, 0f, 1f, 1f, 1f, 1f, 1f );

Ironically, this technique is not as easy on modern, truecolor platforms as it was on the older palettized platforms. In the days of limited colors, this was accomplished by remapping a 2-8 bit color palette of the sprite to different colors, because using 32 bits for one pixel was an unaffordable luxury. Now, we don’t have these palettes to play with, and we just use the full 32-bit color spectrum directly.

Some ways to emulate this technique in a truecolor world:

  • Write a custom shader that can do color replacement and maybe even fully emulate the old color palette functionality (pretty advanced).
  • Dynamically change the texture as RabidCabbage suggests (may be too slow if too much is being changed each frame).
  • Have separate textures/sprites for each color combination (which you didn’t want but it IS the easiest).

Off the top of my head, if I were to do the shader, I’d try having it take 2 texture inputs - the sprite texture, and a palette texture. I would use the color values from sampling the sprite texture to compute a texture coordinate within the palette texture, and then sample that palette texture for the output color.

You can just change the sprite color. This will only affect the particular sprite, not all of them. (Because sprites use vertex colors.)

GetComponent(Sprite).color = ....

This thread talks about shifting hues on a textures, which, I believe, is all that is happening in those examples you posted.