Applying Player Colors

To differentiate between multiple players, it is essential to have visual indicators that show who owns a building or unit. That is why buildings and units mostly just use one specific main color.

To change this, using the colorify Asset and a mask to show which parts of the image can be recolored, we can create textures with one color and easily change them via script.

Using colorify from the asset store we can use a shader to change a specific color on our model to another. The problem with this is that sometimes it isn’t as accurate as we want it to be. When we have a red roof on a house and try to pick that color to change it into another, the brown from our wood, which is basically a darker, less saturated red tone, will also be changed and have random recolored pixels. If we try to lower the replacement range, not all of the roof gets recolored and we end up with a building that is only halfy colored.

The roof isn’t fully changed in color from red to blue, but the door is already showing blue pixels.

Using the masked shader version we can better tell the shader which parts to include and which to leave out, but we have to bake, or edit the texture using alpha values or black/white, meaning the white parts can be affected by the shader, the transparent/black parts are ignored.

The benefit of using a mask with a texture is the result looks a lot better.

Left side shows the house texture, right side shows the mask to specify which parts are recolored.

Now we can nicely recolor buildings if we can make a mask for them. The next problem is, having so many possible playercolors and buildings, we can’t afford to make a material for each building multiplied with each possible player color. That is where material blocks (here is a nice read about material blocks) come into play. Using these, we simply copy the original masked shader from colorify, give it a new name and add [PerRendererData] infront of the “_NewColor” attribute. This means, we can and must change the color of our objects via script.

To do this we make a new Script to utilize the MaterialPropertyBlocks and set the color in the inspector or from another script.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerColor : MonoBehaviour {

    public int playerNumber = 0;
    public GameObject myModel;

    public static Color[] colorList = new Color[]
    {
        //pattern-red: (233,46,46)
        new Color(.85f,0.05f,0.05f),        //Red
        new Color(0.15f,0.35f,0.8f),        //Blue
        new Color(0.670f,0.858f,0f),        //Green
        new Color(0.58f,0.223f,0.705f),        //Purple
        new Color(1f,1f,1f),                //White
        new Color(0.302f,0.302f,0.302f),    //Black
        new Color(0.976f,0.8f,0.7f),        //Orange
        new Color(1f,0.964f,0.113f)            //Yellow
    };
    public static MaterialPropertyBlock[] blockList;

    private Renderer _renderer;
    private MaterialPropertyBlock _propBlock;

    void Awake()
    {
        if (blockList == null) {
            blockList = new MaterialPropertyBlock[colorList.Length];
            MaterialPropertyBlock block;
            Debug.Log ("blocklistnull");
            for(int i = 0; i < colorList.Length; i++) {
                block = new MaterialPropertyBlock();
                block.SetColor("_NewColor", colorList[i]);
                blockList[i] = block;
            }
        }
        _propBlock = blockList[playerNumber];
        _renderer = myModel.GetComponent<Renderer>();
        _renderer.SetPropertyBlock(_propBlock);
    }
}

Enjoy your colored models!
And don’t forget to check “Enable GPU Instancing” on your shader.
Now we have just 1 material for any amount of possible colors and buildings.

Ein Gedanke zu „Applying Player Colors

Schreibe einen Kommentar