Fade a texture at distance

I’m firing a laser and i’d like to have the laser fade out as it approaches the max range. Now i know how to make a texture with a gradient but the issue is if i just faded out towards the end of a texture it would fade out always even across a short distance if drawn between the player ship and the target hit.

So I need it to basically either alter transparency based on distance between 2 vectors or else I guess really what i want is for the texure to be used based on distance. Like if the max range of the weapon is 100 meters at 100 meters use the full left to right range of the texture but at 10 meters just texture the first 10%. Basically so that the fade in on the texture is only applied if the whole texture is. I’m not sure what I want really though, I don’t know what the standard way to do this is. If it’s shader coding or what you do in photoshop or regular coding or what.

Two things came to mind on how to achieve this.

First idea that came to me is that you could start lerping the alpha of the projetile’s material after it’s gotten far enough. You’d need a transparent shader… One of Unity’s should do.

The second is a bit more work, but allows for more impressive projectiles. It’s based on the same principles as texture atlases, except we slide the location we want to show as the projectile moves. You’ll need a gradient (or any, really) image, of which you calculate the correct UV position, based on the distance of the starting location.

I hacked this snippet together for you, it’s for the first option…

Vector3 startingPos = Vector3.zero;
public float maxDistance;
public bool lerping = false;


void Update () {
	//are we far enough?
	if(!lerping && Vector3.Distance(transform.position, startingPos) > maxDistance)
		StartCoroutine(Fade ());
}

IEnumerator Fade(){
	//disable colliders etc. here 
	Color startColor = renderer.material.color;
	float fadeTime = 10f;
	float timer = 0f;
	lerping = true;
	float startingAlpha = renderer.material.color.a;
	float alpha;
	
	while(timer < fadeTime){
		timer += Time.deltaTime; 
		alpha = Mathf.Lerp(startingAlpha,0,timer/fadeTime);
		renderer.material.SetColor("_Color", new Color(startColor.r,startColor.g,startColor.b,alpha));
		yield return null;
	}
	lerping = false;
	Destroy(this);
}

I used the “Transparent/VertexLit” shader because it was pretty.