1
\$\begingroup\$

I have a circular GameObject in Unity 2D with a SpriteRenderer attached.

I want to attach a custom component to my GameObject where I input a value between 0 and 1, with that inputted value corresponding to how much of a pie/cake slice shaped portion (i.e. a sector) of that GameObject I want to be rendered.

For example, see this illustration:

Four images of the same circular sprite, with a quarter, a half, three quarters, and the full sprite visible, in the shape of sectors

These renderings of a sprite would correspond to the values 0.25, 0.5, 0.75, 1 being inputted to my GameObjects custom component.

How do I create such an effect?

I would want different GameObjects to have this effect applied to them at the same point in time, possibly with different inputted values.

I assume I would have to implement this using an Unlit Shader, but I'm not sure quite how to write this shader, as well as have different GameObjects using different values at the same time for the input value.

The GameObject must use a SpriteRenderer, not an Image component.

\$\endgroup\$
1
  • \$\begingroup\$ Keep in mind that you can always use a worldspace canvas to position an Image component in your game's 3D world, just like a SpriteRenderer. So this might not need to be a deal-breaker, if you'd rather get something working out of the box without writing your own shader. \$\endgroup\$ Commented Jan 16 at 14:51

1 Answer 1

4
\$\begingroup\$

If writing a proper HLSL shader seems intimidating, you can always just make a Shader Graph. Here's one I designed that you can copy once you have Shader Graph installed:

Full view of the Shader Graph

The variables (top left) are:

  • T: The 0-1 variable that determines what percentage of the sprite is visible.
  • Start Angle: The angle above the horizontal where the first sliver of the sprite will appear when you make T > 0, expressed in degrees.
  • Clockwise: Determines whether the visible sliver of the sprite will expand clockwise or counterclockwise as T increases. Make sure this is a boolean keyword, or else one of the nodes I've used won't be available.
  • MainTex: As long as you name the variable that, Unity will automatically set it to whatever's in the SpriteRenderer's "Sprite" field.

Close-up view of the leftmost part of the Shader Graph. There might be a more efficient way to do this, I'm admittedly not very familiar with the arc-trig nodes.

The right side of the Shader Graph.

If you don't see the Alpha and Alpha Clip Threshold nodes in the "Fragment" block, go to the Graph Settings and turn on "Alpha Clipping".

Next, create a Material that uses this Shader Graph, which you can do by right-clicking the graph in the Project View and selecting Create -> Material.

Go to the SpriteRenderer on the object you want to apply this effect to, and set the "Material" field to this new Material.

Next, add this script to the object:

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

[RequireComponent(typeof(SpriteRenderer))]
public class RadialWipe : MonoBehaviour
{
    [Range(0, 1)] public float t;
    new SpriteRenderer renderer;

    void Awake()
    {
        renderer = GetComponent<SpriteRenderer>();
    }

    void Update()
    {
        renderer.material.SetFloat("_T", t);
    }
}

Now, if you press play and change t in this script's inspector, you'll see the sprite "filling up" like you wanted. You can even have multiple objects like this, all with different t values. Hope this helped!

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.