Unity: 2D translucent effect when a character is “behind” an object

In 2D games, characters (and sprites) move in an x-y plane corresponding to the screen. In order to create a sense of 3D depth, if an object A is “behind” an object B, then A is drawn on the screen before B, so B’s sprite occludes A.

However, if the object A happens to be the player’s character, then the player may not be able to see their character, or may only see a tiny bit of themselves. One method that 2D games (e.g., role-playing games) employ is to create a translucent effect. In this article, I will discuss how to create such a translucent effect in Unity, and provide some sample code you can download to try out!

Now you see me, now you don’t! The right-most translucent effect is what we’re going for in this guide.

Why am I writing this guide? When I was working on Mystery Queen, I spent some time searching online for a similar guide. I found various forum posts and discussions on how to do it, and some snippets of code that were useful to varying degrees. However, to get a completely working system, I had to essentially use those ideas and implement it myself. Thus, I figured that having a guide and downloadable content online would be useful for others!

The Unity scenes, assets, and source code for this guide are available for download as a Unity package. You can also access the files on Github. There are separate scenes for each step in this guide, so you can pick and choose how you want to follow along. The project and code have been created to be easier to understand over efficiency, so you may want to do some optimizations and customizations for your own project.

Step 0: Setting up the scene in Unity

We’re going to set up a basic scene in Unity, with 2 sprites: a tree, and a character. We’re using freely-available sprites from the Liberated Pixel Cup (LPC): a tree sprite from the [LPC] Trees set and the [LPC] Sara sprites.

Sara (the character) has been set up with CapsuleCollider2D and RigidBody2D components, as well as a basic script to move her left and right depending on the player’s input. Sara has a SpriteRenderer and Animator to animate her movement.

The tree is a game object with a SpriteRenderer that displays the tree, and nothing else (for now).

Both Sara and the tree have their SpriteRenderers rendering on the same layer (Default) with the same order in the layer (0). The project has been set up so that sprites are rendered based on their y-position, i.e., a sprite with a higher y-position will be rendered after (equivalently: on top of) a sprite with lower y-position.

Sara gets occluded by the tree when she walks behind it.

From this basic scene (Step 0 in the Unity project), you can move Sara left and right, and notice that Sara will get occluded by the tree when she is behind it!

Step 1: Setting up a collider for the tree

In order for Sara to detect that is behind a tree, we will need to set up a collider of some sort. In this case, we will use a Polygon2D collider (although you can use other colliders for your sprites) that we will set up as a trigger.

We’ve also tagged the tree game object with a new tag, “Occludable” (which may or may not be an actual word 😅

To test that our collider is working, we’ve also created a new behavior for Sara, an OcclusionDetector, that implements the OnTriggerEnter2D and OnTriggerExit2D methods:

void OnTriggerEnter2D(Collider2D collider2D)
{
if (collider2D.gameObject.CompareTag("Occludable"))
{
Debug.Log("Entered an occludable region!");
}
}
void OnTriggerExit2D(Collider2D collider2D)
{
if (collider2D.gameObject.CompareTag("Occludable"))
{
Debug.Log("Exited an occludable region!");
}
}

For now, this method doesn’t really do anything, other than check that the trigger is tagged with “Occludable”, and prints a debug statement to the console.

Feel free to check of the Step 2 scene in the sample Unity project!

Step 2: Turning the tree translucent

In general, SpriteRenderer components have a color field that determines how the sprite should be rendered. By default, the color is set to RGBA (1, 1, 1, 1), which is totally white and opaque. This means that the sprite should be rendered exactly as the source texture. On the other hand, if the color is set to RGBA (1, 0, 0, 1) for example, then the sprite will be rendered with a red tint.

In particular, the “A” element of the RGBA refers to alpha, or how opaque the sprite will be. An alpha of 1.0 means the sprite is totally opaque, and 0.0 means the sprite is totally transparent. Numbers in between (e.g., 0.5) would mean that the sprite is translucent.

Hence, to make our tree sprite translucent, we should set the SpriteRenderer’s color to something other than (1, 1, 1, 1)!

To do this, we will modify the OnTriggerEnter2D and OnTriggerExit2D methods, to grab the SpriteRenderer component of the trigger’s game object, and directly set its color.

void OnTriggerEnter2D(Collider2D collider2D)
{
if (collider2D.gameObject.CompareTag("Occludable"))
{
SpriteRenderer spriteRenderer = collider2D.GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
spriteRenderer.color = new Color(1.0f, 1.0f, 1.0f, 0.5f);
}
}
}
void OnTriggerExit2D(Collider2D collider2D)
{
if (collider2D.gameObject.CompareTag("Occludable"))
{
SpriteRenderer spriteRenderer = collider2D.GetComponent<SpriteRenderer>();
if (spriteRenderer != null)
{
spriteRenderer.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
} }
}

With these changes, the tree now becomes translucent when Sara walks behind it!

The tree now turns translucent when Sara is behind it.

How we did it for Mystery Queen

In Mystery Queen, we used a very similar system. What’s nice about this approach is that we only have to tag objects with the “Occludable” tag and set up a collider, and the translucency pretty much takes care of itself.

One piece of complexity we ran into was that Elise, our main character, isn’t animated via a sprite sheet (which Sara uses). The different components of Elise are rendered at different orders in the layer. All these orders were at a value higher than the other objects (like trees), which meant that Elise would be rendered on top of everything else, even if she walked behind them.

To get the translucency working properly, we set up a additional rendering layer above Default, and when OnTriggerEnter2D is called, we set the object’s SpriteRenderer’s layer to the upper layer and its color to be translucent. When OnTriggerExit2D is called, we reset the SpriteRenderer to the original layer and restored its color.

I hope you enjoyed this guide on adding translucency to objects! Stay tuned for more Unity-related guides as we discuss other systems that we developed (and are developing) for Mystery Queen. If you’re interested, you can also read my next guide on creating a day-night cycle linked below:

Proud mom, roboticist, software engineer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store