[C#] Line Renderer beam not going straight

Hello!

I need help.

I’m making a Wave Motion Gun from Space Battleship Yamato.
The script shoots a straight beam if nothing is in front of it, and if there is, end position of the line renderer would be the RaycastHit point.

Picture of it working firing straight into space:
PICTURE

Picture of hitting a target:
PICTURE2

Picture after target was destroyed, the beam isn’t shooting straight anymore:
PICTURE3

This is the code:

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(LineRenderer))]

public class WaveCannon : MonoBehaviour
{

    public float Damage = 1.0f;

    public AudioSource audioSource;

    public Transform LaserFiringPoint;
    public float LaserMaxDistance = 10.0f;

    LineRenderer linerenderer;

    public AudioClip WaveGunCharge;
    public AudioClip WaveGunPrefire;
    public AudioClip WaveGunLaser;

    public ParticleSystem ChargingObject;
    public ParticleSystem PrefireObject;
    public ParticleSystem FiringObject;
    public GameObject FiringEndObject;

    public float LaserReachSpeed;

    bool Firing = false;

    private float beginTime;

    Vector3 HitPoint;

    private bool canDamage = false;

    GameObject hitThing;


    void Start()
    {
        linerenderer = GetComponent<LineRenderer>();
        linerenderer.GetComponent<Renderer>().enabled = false;
        Firing = false;

        ChargingObject.Stop();
        PrefireObject.Stop();
        FiringObject.Stop();
    }

    void Update()
    {

        if (Firing)
        {

            RaycastHit hit;

            float smoothMove = (Time.time - beginTime) * LaserReachSpeed;
            linerenderer.SetPosition(0, LaserFiringPoint.position);

            Vector3 fwd = LaserFiringPoint.TransformDirection(Vector3.forward);

            if (Physics.Raycast(LaserFiringPoint.position, fwd, out hit, LaserMaxDistance))
            {
                linerenderer.SetPosition(1, Vector3.Lerp(LaserFiringPoint.position, hit.point, smoothMove));
                Debug.DrawLine(LaserFiringPoint.position, hit.point);
                HitPoint = hit.point;
                canDamage = true;
                hitThing = hit.transform.gameObject;
            }
            else
            {
                linerenderer.SetPosition(1, Vector3.Lerp(LaserFiringPoint.position, fwd * LaserMaxDistance, smoothMove));
                canDamage = false;
                hitThing = null;
            }

        }
        else
        {

            if (Input.GetKeyDown("g"))
            {
                Charging();
            }

        }

    }

    void Charging()
    {

        ChargingObject.Play();
        audioSource.PlayOneShot(WaveGunCharge);
        Invoke("Prefire", WaveGunCharge.length);

    }


    void Prefire()
    {

        PrefireObject.Play();
        ChargingObject.Stop();
        audioSource.PlayOneShot(WaveGunPrefire);
        Invoke("Fire", WaveGunPrefire.length);

    }

    void Fire()
    {
        beginTime = Time.time;
        Firing = true;
        FiringObject.Play();
        PrefireObject.Stop();
        linerenderer.GetComponent<Renderer>().enabled = true;
        audioSource.PlayOneShot(WaveGunLaser);
        Invoke("AfterFire", WaveGunLaser.length);
        InvokeRepeating("DamageEffect", 0.0f, 0.05f);

    }

    void DamageEffect()
    {
        if (canDamage)
        {
            Instantiate(FiringEndObject, HitPoint, transform.rotation);
            hitThing.SendMessage("Damage", Damage, SendMessageOptions.DontRequireReceiver);
        }
    }


    void AfterFire()
    {
        CancelInvoke("DamageEffect");
        FiringObject.Stop();
        linerenderer.GetComponent<Renderer>().enabled = false;
        Firing = false;
    }


}

Well your problem is that in the case where you don’t hit anything you set the second point to:

Vector3.Lerp(LaserFiringPoint.position, fwd * LaserMaxDistance, smoothMove)

The problem here is that “LaserFiringPoint.position” is a world space point but “fwd * LaserMaxDistance” is just a world space direction and not a point. So the resulting positiob will be around the world origin.

You might want to use this instead:

linerenderer.SetPosition(1, LaserFiringPoint.position + fwd * LaserMaxDistance * Mathf.Clamp01(smoothMove));