Fading Alpha based on proximity

I had an awesome snippet somewhere to refer to but cannot for the life of me find it. I think it used a mathf class.

The basic principle is that one value changes based on the value of another.

So if object is at greater distance than myProximity, the alpha is 0
if at less distance than myProximity, the alpha value increases.

When player distance is equal to 0 from my proximity the alpha value is 1.

Can anyone give me a pointer as to what the technique might be here?

Cheers

AaronC

Hi Aaron,

I understand you know how to get the distance to an object and pass a variable to it. Specifically blending the material alpha channel is done in the shader. All you need to do is take a default shader, add a slider “opacity” or whatever, then multiply the alpha with that before outputting it. Then you can just reference the material in code and modify the slider to change opacity. A similar technique is used for blending two textures together, I use it for Day/Night skyboxes, and for that I do indeed use mathf.lerp to get a smooth transition. The wiki has a “blend 2 textures” shader as an example. Here’s an UAnswers topic with what you seem to be looking for as first answer.

You can do something like this…

using UnityEngine;

public class FadeScript : MonoBehaviour
{
    [SerializeField] private GameObject _sphere;
    [SerializeField] private GameObject _cube;

    private float _myProximity = 5;
	
	void Update ()
	{
	    float absoluteDistance = Mathf.Abs(Vector3.Distance(_cube.transform.position, _sphere.transform.position));
        
	    if (absoluteDistance > _myProximity)
            _sphere.renderer.material.color = new Color(1, 1, 1, 0);
	    else if (absoluteDistance < _myProximity  absoluteDistance > 0)
	    {
	        float alpha = 1 / absoluteDistance / _myProximity; // Get the inverse as it gets closer
            _sphere.renderer.material.color = new Color(1, 1, 1, alpha);
	    }
	    else
            _sphere.renderer.material.color = new Color(1, 1, 1, 1);

	    Vector3 _cubePos = _cube.transform.position;
	    _cube.transform.position = new Vector3(_cubePos.x + Input.GetAxis("Horizontal"), _cubePos.y, _cubePos.z);
	}
}

Just assign a cube and a sphere to the script at design time, then make sure you set the sphere’s material to be transparent (i.e a material with an alpha channel.)

As you move the left and right arrow keys, you will see it fade in/out and blank out when proximity has been exceeded.

Thanks guys this should get me going.

No need to overcomplicate things. :wink: (Also, Vector3.Distance can never be negative anyway.)

var proximity : float;
var target : Transform;

function Update () {
	renderer.material.color.a = Mathf.InverseLerp (proximity, 0.0,
		Vector3.Distance (target.position, transform.position));
}

–Eric

2 Likes

Well there you go again, making me and C# look bad, and UnityScript look good :sad:

Thanks Eric.

I’ve got a strange thing where when I lerp to “opaque” the alpha is at about 0.8 rather than 1.0. Any idea why that would be?

[FONT=Menlo][COLOR=#3363a4]function[/COLOR][COLOR=#444444]Update[/COLOR][COLOR=#444444]() {[/COLOR]

[COLOR=#009695]if[/COLOR][COLOR=#444444]([/COLOR][COLOR=#444444]moving[/COLOR][COLOR=#444444])[/COLOR]
[COLOR=#444444]player[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]position[/COLOR][COLOR=#444444] = [/COLOR][COLOR=#444444]Vector3[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]Lerp[/COLOR][COLOR=#444444]([/COLOR][COLOR=#444444]player[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]position[/COLOR][COLOR=#444444], [/COLOR][COLOR=#444444]transform[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]position[/COLOR][COLOR=#444444]+[/COLOR][COLOR=#444444]Vector3[/COLOR][COLOR=#444444]([/COLOR][COLOR=#f57c00]0[/COLOR][COLOR=#444444],[/COLOR][COLOR=#444444]yOffsetOnceMoved[/COLOR][COLOR=#444444],[/COLOR][COLOR=#f57c00]0[/COLOR][COLOR=#444444]), [/COLOR][COLOR=#444444]movingSpeed[/COLOR][COLOR=#444444] * [/COLOR][COLOR=#444444]Time[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]deltaTime[/COLOR][COLOR=#444444]);[/COLOR]

[COLOR=#444444]renderingBubbleMaterial[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]color[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]a[/COLOR][COLOR=#444444] = [/COLOR][COLOR=#444444]Mathf[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]InverseLerp[/COLOR][COLOR=#444444] ([/COLOR][COLOR=#444444]proximity[/COLOR][COLOR=#444444], [/COLOR][COLOR=#f57c00]0.1[/COLOR][COLOR=#444444], [/COLOR][COLOR=#444444]Vector3[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]Distance[/COLOR][COLOR=#444444] ([/COLOR][COLOR=#444444]player[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]position[/COLOR][COLOR=#444444], [/COLOR][COLOR=#444444]transform[/COLOR][COLOR=#444444].[/COLOR][COLOR=#444444]position[/COLOR][COLOR=#444444]));        [/COLOR]

[COLOR=#444444]}[/COLOR][/FONT]

The forum doesnt like monodevelop apparently:

function Update() {

if(moving)
player.position = Vector3.Lerp(player.position, transform.position+Vector3(0,yOffsetOnceMoved,0), movingSpeed * Time.deltaTime);

renderingBubbleMaterial.color.a = Mathf.InverseLerp (proximity, 0.1, Vector3.Distance (player.position, transform.position));

}

My code doesn’t have this problem :slight_smile:

Mine doesn’t either. :wink: Try printing out the various values (Distance, InverseLerp) to see what the actual numbers are.

–Eric

:frowning:

It was a y-axis offset. I changed from Vector3 to Vector2 and got the nice result I was after.

Thanks again!

You guys :lol: