Brave Battle: World War II is a FPS Mulplayer developed in the Unity engine. The main focus of the project is to ensure immersion, historical acurracy (weapons, locations, etc.) and try to bring good gameplay. Developed sole. Status: in development.

Post tutorialReportRSSUnity Tutorial / Explanation: Using masks and colors to improve the detection of object surfaces

There are several tutorials in Unity for how to recognize the surface of an object using a trigger collider or using raycasts, some techniques will even get the index of terrain texture for footsteps, but when you want to get the reference of 1 type of texture between several in 1 material (or more) assigned to an object? In this article I will show you how to use the properties and color classes and masks of materials of unity applied to the mesh for example making a footstep in a plane.

In this article I will show in the Unity tool how to improve the detection of the materials or textures by the collisions using a mask and a color reference. In my game (Brave Battle) I was frustrated at having to for every surface to have by a collider to detect its property in order to play a sound of footsteps or use exact particles. Taking a closer look at the internet, I found the FMOD (sound effects engine) tutorial where it was shown how to make a footsteps system using a mask.

With this I improved on this idea, expanding it so that I can recognize where each texture is in 1 single material using as base a mask (DetailMask) filled with the color id of the texture of the object and doing a color reference with a small database.

In the image below is shown the texture id map and albedo color, this process is to have a single material with multiple textures (Substance Painter and Blender used in this textures):

Here below the id map image assigned to the Input Detail Mask of its respective material:

How the process works:

In unity there is a function / method in the texture class that returns a filtered pixel color at normalized coordinates (UV). Using this to get the color of the mask (DetailMask) and make a reference comparing the RGB values of the returned color to a color saved in a database / color list, so if the returned color is equal to the reference color, it can be for example "wood equals to red color", can execute the surface event (footstep, effect, particle ...).

First we throw a raycast on the floor to get the material, we check the index of the material by GetTriangles method and once we have the correct material, we call the GetPixelBilinear method:

RaycastHit hit;
if (Physics.Raycast(transform.position, -Vector3.up, out hit, Mathf.Infinity)) { //Cast a raycast from player to ground
int materialIndex = GetMaterialIndex(hit); //check current material hitted (if more then one)
if (materialIndex != -1) { //Check if returned index value is not null
Material material = hit.collider.transform.GetComponent<Renderer>().materials[materialIndex]; //references the index with the getted material
if(material.name == "Plane (Instance)"){ //Instance is because on runtime unity creates a new object for material
hittedColor = GetPixelBilinear(material, hit.textureCoord, textureMaskPrefix); //Saves returned color in a variable
}
}
}

We could use Equals to compare the colors but it would return the exact value of the RGB values, and sometimes because it is accurate it does not recognize the color. The solution is to create a method to get the approximate value of the RGB values using a threshold for margin of error:

That way we can make the reference of the color taken by raycast to a variable that we already have, and by comparing them we can carry out an event. A good implementation is to create a list that references colors and its name or sound for example to have all the references of the texture of the object. Here's an implementation made like this:

Below a video showing the functional concept could easily be implemented for the hit effect of a gun or footsteps:

For doubts send an email to me, it is not every time I can respond because of the area that I live that sometimes does not have access to the internet, but if you see the email I respond. Email: thomaspontes13@gmail.com

Post a comment

Sign in or join with:

Only registered members can share their thoughts. So come on! Join the community today (totally free - or sign in with your social account on the right) and join in the conversation.