RayCast, origin not updating fast enough

I made a laser system for the guns in my game, it works fine but when I move the character it seems the origin of the RayCast its not updating fast enough and its not moving with the gun but a bit slower, here its my code also I included some pictures of the problem (in the second picture I meant to write “Laser not moving with the gun”):

I have been testing a number of solutions including adding the script directly to the gun so I narrowed it down to RayCast Origin.

Im really worried about this, if I cant make this be accurate the bullets are gonna be really inaccurate, also it looks very bad, laser sigths are suppose to be really reliable and accurate.

using UnityEngine;
using System.Collections;

[AddComponentMenu("Rayco's scripts/Laser")]
public class laser : MonoBehaviour {
	public GameObject weapon;
	public int LaserLength;
	public Vector3 RotationOffset;
	public Vector3 PositionOffset;
	public Material LaserMaterial;
	public Color LaserColor;
	public Color LaserEndColor;
	public float LaserStartWidth;
	public float LaserEndWidth;
	Ray ray;
	void Start () {
		
		LineRenderer lineRenderer = gameObject.AddComponent<LineRenderer>();
		transform.position = weapon.transform.position;
		transform.parent = weapon.transform;
		transform.localEulerAngles = RotationOffset;
		transform.localPosition = PositionOffset;
		//LineRenderer options
		lineRenderer.material = LaserMaterial;
		lineRenderer.SetColors(LaserColor,LaserEndColor);
		lineRenderer.SetVertexCount(2);
		lineRenderer.SetWidth(LaserStartWidth,LaserEndWidth);
		lineRenderer.useWorldSpace = true;
		
		
	}
    void Update() {
		//LineRenderer
		LineRenderer lineRenderer = GetComponent<LineRenderer>();
		//Raycast stuff
		ray.origin = transform.position;
		ray.direction = transform.forward;
		RaycastHit hit;
		lineRenderer.SetPosition(0,ray.origin);
		if (Physics.Raycast (ray, out hit, LaserLength)){
		//Debug.DrawLine draws a line on game view, I have it for testing pourposes, you may delete any reference to it
        Debug.DrawLine(ray.origin, hit.point, Color.red);
		lineRenderer.SetPosition(1,hit.point);	
		}
		else{
		Debug.DrawLine(ray.origin,ray.GetPoint(LaserLength), Color.red);
		lineRenderer.SetPosition (1,ray.GetPoint(LaserLength));
		}
    }
	
}

Since a LineRenderer is a component attached to a gameobject, why not just using local space coordinates?

LineRenderer m_LineRenderer;

void Start ()
{
    // ...
    m_LineRenderer = GetComponent<LineRenderer>();
    // ...
    m_LineRenderer.SetVertexCount(2);
    m_LineRenderer.useWorldSpace = false;  // use local space
    
    m_LineRenderer.SetPosition(0,Vector3.zero);
}

void Update()
{
    // ...
    if (Physics.Raycast (ray, out hit, LaserLength))
    {
        m_LineRenderer.SetPosition(1,new Vector3(0,0,hit.distance));
    }
}

hit.distance works because your LineRenderer objects forward direction points in the same direction as your ray.

As alternative you can use InverseTransformPoint like this:

    if (Physics.Raycast (ray, out hit, LaserLength))
    {
        var P = m_LineRenderer.transform.InverseTransformPoint(hit.point);
        m_LineRenderer.SetPosition(1, P);
    }

I have the same problem before, it is with a 2D marker tracking a 3D scene object. I came out with 2 different solutions for my problem.

How about using LateUpdate() instead of Update() in your laser script? It is possible that the Update() from your laser script is run before the Update() of your movement script. Hence there is a slight inaccuracy everytime you move and yet, everything looks fine when you are not moving.

Another possible solution is to redraw the laser in your movement script:

public class laser : MonoBehaviour {
   ...

   void Start() {
      ...
   }

   void Draw() {
      //LineRenderer
      LineRenderer lineRenderer = GetComponent<LineRenderer>();
      //Raycast stuff
      ray.origin = transform.position;
      ray.direction = transform.forward;
      ...
   }
}

Then in your movement script:

public class movement : MonoBehavior {
   public Laser laser;
   ...
   ...
   void movementfunction() {
      ...
      //Call the Draw() at the end of your movement
      laser.Draw();
   }
}

By following any of these 2 method, the laser will always be drawn after the movement is calculated at each frame of your game. Hopes that this will help you.