Script for shooting with a LineRender (Laser Weapon)

I am modding Unity Tanks!, a game from a 2015 tutorial. In the game two players control two tanks on one keyboard and have to destroy the opponent by shooting shells at them. I want to add new secondary weapons for the players to use. for simplicity's sake I am going to assign them to dedicated secondary fire buttons.

I first created a WeaponHolder object where to store the weapons. I start working on a Laser Beam (a continuous laser), as a child item of the WeaponHolder. I drew it with a line renderer (I don't think I need to add colliders and rigidbody?). Online I found and attached this script for the laser behaviour.

public class LineLaser : MonoBehaviour
{

    private LineRenderer lr;

    // Start is called before the first frame update
    void Start()
    {
        lr = GetComponent<LineRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        lr.SetPosition(0, transform.position);
        RaycastHit hit;
        if (Physics.Raycast(transform.position, transform.forward, out hit))
        {
            if (hit.collider)
            {
                lr.SetPosition(1, hit.point);
            }
        }
        else lr.SetPosition(1, transform.forward * 5000);
    }
}

The way the original game is designed there is one tank prefab that gets cloned in two variants (red and blue) (GameManager.cs does it). the tank holds the shooting script while the shell is a separate prefab that holds a script for the impact explosion and damages count.

I would like to keep the same organisation for my mods, with one minor difference: the laser prefab must exist as a child of the WeaponHolder because the player will pickup a "?" block on the map in the style of Mario Kart, which will randomply pick a powerup weapon in the WeaponHolder.

That said, while the laser hold the script above, the tank should control the shooting (but fails) with the following:

public class WeaponLaser : MonoBehaviour
{
    public int m_PlayerNumber = 1;
    public Transform firePoint;
    public GameObject laserPrefab;
    private string SpecialButton;
    private LineRenderer lr;

    private void Start()
    {
        SpecialButton = "Special" + m_PlayerNumber;
        lr = GetComponent<LineRenderer>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetButtonDown(SpecialButton))
        {
            Shoot();
        }

        void Shoot()
        {
            //shooting logic
            Instantiate(laserPrefab, firePoint.position, Quaternion.identity);
            laserPrefab.GetComponent<LineRenderer>.Invoke();

        }
    }
}

I know. It's definitely not .Invoke(), but I had to try with something... Help! Firepoint is an empty object on the tank cannon and laserPrefab obvs refers to the laser prefab (but does not follow the behavioural script attached? maybe?).

Little note: m_PlayerNumber refers to the way the game handles cloning and, here specifically, the 2-in-1 input system. This is also giving me problems, but so far I would be content if even one single tank was able to shoot this laser.

If I manage to solve this I will probably come back here to also deal with the laser impact and explosion, but so far please help me fix this one here! :)

First, a couple notes… make sure your Shoot() method is outside of your Update method, otherwise the compiler will complain. Also for these lines

Instantiate(laserPrefab, firePoint.position, Quaternion.identity);
laserPrefab.GetComponent<LineRenderer>.Invoke();

Instantiate will create a copy of laserPrefab and put it in the world. Using laserPrefab on the following line will use the original (which probably doesn’t exist in your scene), not the copy that does exist in your scene. If you want to access the object that Instantiate creates, do something like

GameObject newLaser = Instantiate(blah blah);
newLaser.GetComponent<blah blah>();

**
So there are a few ways that you can do this, but be careful not to overcomplicate things. You mention that you would like to make the laser a prefab like the bullets that the main weapon shoots. While you can go down this path (I’ll help if you shoot me a reply) I strongly recommend against it. There is only one laser per tank, so it would be easiest just to have the laser there all the time, but just have it disabled.
**
With that in mind I recommend making a gameobject that is your laser weapon (with your WeaponLaser script) and put it as a child of your weapon holder. You can set this weapon as inactive until you pick up the powerup box. Next I would make the laser object as a child of the weapon. It will hold the actual line renderer and the LineLaser script. Then you can modify your WeaponLaser script like so -

public class WeaponLaser : MonoBehaviour {
    public int m_PlayerNumber = 1;
    public Transform firePoint;

    //Set this to the child laser object. This should not be a prefab.
    public LineLaser laser;

    private string SpecialButton;
    private LineRenderer lr;

    private void Start () {
        SpecialButton = "Special" + m_PlayerNumber;
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetButton (SpecialButton)) {
            Shoot ();
        }
        else{
            TurnOffLaser();
        }
    }

    void Shoot () {
        //Shooting logic
        laser.gameObject.SetActive(true);
        //Do damage here
        //In your LineLaser script you could find the object that the raycast hits (hit.gameObject will give you the gameObject)
        //Then you could grab that object here and do damage or whatever you want
    }

    void TurnOffLaser(){
        laser.gameObject.SetActive(false);
    }
}