Need help setting correct Y height for laser beam with 50 elements

K so I have a laser set up in my game which is using a Line Renderer which shoots up to 50 individual particles or “Elements” to create the visual laser effect. This allows the laser to kind of pulsate due to a “noise” variable causing the x and z positions to change positions slightly along the path.

Everything is working well except one thing. I’m not sure how to go about setting the Y height properly since each of the 50 elements need to have a custom y height. Currently the ray just keeps the same y-height as how it starts which works fine for some enemies but shoots over the head of others so I have to make the enemy colliders taller and it just looks unnatural when the laser isn’t hitting their body.

I’ve tried some solutions but have been unable to get it work correctly so far. This kind of math is not my strong point and with the individual element system I’m not sure if it’s even possible with my current system but I was hoping someone might have some answers and advice for me.

Example of the laser code which sets the offset positions (x, y, z) for each of the 50 elements. Not all 50 elements will be used if the laser hits a target before it’s max range.

     void RenderLaser()
        {
        
        //length = 50
        for(int i = 0; i<length; i++)
        {
        //offset is a vector position for each of the 50 elements
        //player will be facing the target with other controls
        
        offSet.x = myTransform.position.x + i*myTransform.forward.x + Random.Range(-noise,noise);
        
        offSet.z = i*myTransform.forward.z + Random.Range(-noise,noise) + myTransform.position.z; 
        
        //here is the problem I need to set the Y height correctly
        //currently using
        offSet.y = myTransform.position.y;
        
        position *= offSet;*

lineRenderer.SetPosition(i, position*);*
}
So I have access to the gameObject that the laser is hitting, so I would think that I should be able to somehow set the y positions correctly based on what % of distance they are from the player to the enemy?
Right now I had it set up so RenderLaser() is called every Update() perhaps fixedUpdate() would be better for these calculations, not sure if it should matter it is a visual effect so Update should work?
I’ve tried a bunch of stuff trying to set the y height based on the start of laser position from the player and the enemy transform position, but like I said math is not my strong point and the unique elements are kinda throwing me off.
Examples of how I’ve tried to set y height:
//the laser destination position
laserTargetVector = damageHit.collider.gameObject.transform.position;

//distance from laser start to finish
float distanceToEnemy = Vector3.Distance (myTransform.position, laserTargetVector);

//attempt to get the y height change to calculate slope
float newOffSetYCalculation = myTransform.position.y - laserTargetVector.y;

//I would think I should be able to solve with just the 3 pieces of info above but I’m not quite getting it seems like

//Here’s another example of something I’ve tried I think this is the closest solution I’ve had
//but there’s so many comments from all the things I’ve tried
//things getting really messy to keep track of

float slopeRatio = (myTransform.position.y - laserTargetVector.y)/(myTransform.position.x - laserTargetVector.x);

offSet.y = myTransform.position.y - (slopeRatio*i);

I think those are some decent examples of what I’m trying to do. I just feel like I’m a bit out of my league mathematically here. It seems like I should be able to use the slope ratio in relation to my offset.y position to do this. The trouble seems to be that I’m not sure how to determine the y position for each of the 50 elements accurately. I need to determine the % of distance each y particle is from the player to enemy to determine height.
I’m not sure if this is possible with the element system since I’m not sure if they are always spaced out consistent distances since this is called from Update, and since it’s not always 50 elements if the laser doesn’t go the full length it makes things even more complicated.
I’m thinking maybe I need to get the distance of every y particle before setting the height, so set the x and z position first then get that position to calculate y height?
I dunno this is very complicated for me hopefully someone can help!
Essentially I just want the unique particles to follow the exact path a normal line renderer would be from the player’s hand to the enemies body. I know how to do this but not with the 50 element line renderer thing I’m trying to work with.

You could calculate the positions like this.

1.Calculate the “ideal” line between the source of the lazer and its target (target.position-transform.position).

2.For the " i’th " point in the line, assign it the position i*(ideal/50). At this point the line renderer is just a straight line from the source to the target.

3.Add a random “noise” vector to each point.

An example script using this method below:

using UnityEngine;
using System.Collections;

public class laserScript : MonoBehaviour {
	public Transform target;
	public float noise =5f;
	private LineRenderer laser;
	void Awake(){
		laser=GetComponent<LineRenderer>();
	}
	void Update(){
		render_line();
	}
	void render_line(){
		for(int i=0;i<50;i++){
			laser.SetPosition(i,calculateIthPosition(i));
		}
	}
	Vector3 calculateIthPosition(int i){
		Vector3 ideal=(target.position-transform.position);
		Vector3 ithIdeal = i*(ideal/50);
		return transform.position+(ithIdeal+noiseVector()); 
		//I was getting some weird results with just "ithIdeal+noiseVector()", 
		//but i think that was because I had 
        //"use world space" on in the line renderer
	}
	Vector3 noiseVector(){
		return (Random.onUnitSphere*noise);
	}
}

and here is a picture of the code working

[16889-laser+example.jpg|16889]

is this the sort of effect you were going for?

P.S.
Your idea is very clever. I would have never thought to use a line renderer like that.

I have to agree with @mattmanj17. Your idea is clever. Here is my take at a solution. Before you attempt to integrate it into your app, test it in a clean scene to make sure it is what you are going for:

  • Create a game object near the camera for your fire point.

  • Add a LineRenderer component to the game object. Set the material and width as appropriate.

  • Add this script.

  • Put an object in the scene to act as a target.

  • Initialize the ‘target’ of the script in the inspector by dragging and dropping the target game object from hierarchy onto the ‘target’ variable.

  • Hit play. Move the target around in the inspector.

    using UnityEngine;
     using System.Collections;
     
     public class Laser : MonoBehaviour {
     	public int length = 50;
     	public float noise = 0.1f;
     	public Transform target;
     	
     	private LineRenderer lineRenderer;
     	
     	void Start () {
     		lineRenderer = GetComponent<LineRenderer>();
     		lineRenderer.SetVertexCount (length+1);
     	}
     	
     	void Update() {
     		RenderLaser(transform.position, target.position);	
     	}
     	
     	void RenderLaser(Vector3 startPos, Vector3 endPos) {
      		Vector3 targetVector = endPos - startPos;
     		float lineLength = targetVector.magnitude;
     		targetVector = targetVector.normalized * lineLength / length;
     		Vector3 ortho = Vector3.Cross (targetVector, Vector3.up).normalized;
     		Vector3 ongoing = startPos;
     		
             lineRenderer.SetPosition(0, startPos);
     		
             for(int i = 1; i <= length; i++) {
     	   		ongoing += targetVector;	
     	        Vector3 offset = Quaternion.AngleAxis(Random.Range(0.0f, 360.0f), targetVector) * (ortho * Random.Range (0.0f, noise));
     	        lineRenderer.SetPosition(i, ongoing + offset);
             }
     	}
     }