[SOLVED ] Problem with Line Renderer Positions?

Hi everyone,

I am new to unity so bear with me on this.

I have a strange issue with the Line Render function in unity, I am not sure how to get around this problem and have spent a while trying to work it out but seem to be getting no where. What I am trying to achieve is drawing a line between the “fire point” on the tower and the enemy position. This works fine if the Prefab of the tower is already in the scene but when I build an instantiated version that’s when it all goes wrong.

The left is the “play” screen, the green arrow is pointing to the built tower in the scene and the red arrow with the ?? is pointing to where the line is being drawn. The Blue circles are the “enemy” which is stored in a “target” gameobject.
The prefab has an empty game object called “Fire Point” and the “lineRenderer” is a reference to the line renderer component attached to the tower.

In short the line renderer isn’t drawing a line in the correct place and it appears randomly in the scene view even though the positions are referenced correctly.

Thank you if anyone can help me with this as I have been really struggling.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LaserTurret : MonoBehaviour
{


    private Transform target;
     public float range = 15f;

    [Header("Use Bullets (Default)")]
    public GameObject bulletPrefab;
    public float fireRate = 1f;
    private float fireCountdown = 0f;

    [Header("Use laser")]
    public bool useLaser = false;
    public LineRenderer lineRenderer;

    [Header("Setup Fields")]

    public string enemytag = "enemy";

    public Transform partToRotate;
    public float turnSpeed = 10f;


    public Transform firePoint;



    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("UpdateTarget", 0f, 0.5f);
    }

    void UpdateTarget ()
    {
        GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemytag);
        float shortestDistance = Mathf.Infinity;
        GameObject nearestEnemy = null;

        foreach (GameObject enemy in enemies)
        {
            float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
            if (distanceToEnemy < shortestDistance)
            {
                shortestDistance = distanceToEnemy;
                nearestEnemy = enemy;
            }
        }

        if (nearestEnemy != null && shortestDistance <= range)
        {
            target = nearestEnemy.transform;
        } else if ( nearestEnemy != null && shortestDistance > range )        {
            target = null;
        }
    }

    // Update is called once per frame
    void Update()
    {
        if ( target == null)
        {
            if(useLaser)
            {
                if (lineRenderer.enabled)
                    lineRenderer.enabled = false;
            }
            return;
        }
           

        LockOnTarget();

        if (useLaser)        {
            laser();
        }
        else        {
            if (fireCountdown <= 0f)
            {
                Shoot();
                fireCountdown = 1f / fireRate;
            }

            fireCountdown -= Time.deltaTime;
        }

       
    }

    void LockOnTarget()
    {
        Vector3 dir = target.position - transform.position;
        Quaternion lookRotation = Quaternion.LookRotation(dir);
        Vector3 rotation = Quaternion.Lerp(partToRotate.rotation, lookRotation, Time.deltaTime * turnSpeed).eulerAngles;
        partToRotate.rotation = Quaternion.Euler(0f, rotation.y, 0f);
    }

    void laser()    {
        if (!lineRenderer.enabled)
            lineRenderer.enabled = true;


        lineRenderer.SetPosition(0, firePoint.position);
        lineRenderer.SetPosition(1, target.position);
    }

    void Shoot()
    {
       GameObject bulletGO = (GameObject)Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
        Bullet bullet = bulletGO.GetComponent<Bullet>();

        if (bullet != null)
            bullet.Seek(target);
    }

    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, range);
    }

}

I am wondering what “FirePoint” gets assigned to?

So you have that empty gameobject as a child to the tower prefabs themselves that gets saved into the prefab, but it might be a good idea to check what the “FirePoint.Position” actually is set as after the instantiation.

I’d start with debugging there, and figure out why it gets set to something other than what your trying to set it to, then try to figure out the end point after that.

Check if the line renderer is set to use world or local space.

21 Likes

THANK YOU! Seriously, I can’t believe it was that simple. Thank you!

2 Likes

WTF. I spend almost an hour check the LR component by mySelf and double-check the “0” and “1” position inside that component. I should Watch your reply first. TIme Saver and project Saver!!!

2 Likes

wow thank you man it helped me a lot

bruh i could have saved 3 hours of my life by checking a box

3 Likes

Another fun fact about the line renderer, straight from Unity’s documentation:

This method (SetPositions) is preferred to SetPosition when setting all positions, as it is more efficient to set all positions using a single command than to set each position individually. Note that positionCount must be called before SetPositions. Also SetPositions ignores points with indices beyond positionCount.

So if you’re trying to set line positions on the fly from a variable array/list, set positionCount first to your new array size and THEN call the SetPositions with your new array. This feels kind of dumb to me since it feels tailor made to a very specific situation, but just figured I’d add this in case it helps someone else.

9 Likes

man your suggestion is even helping my out like 4 years later. I spend 4 fking hours debugging and found I could solve this by hitting that little button. THANK YOU!