Script not work properly when set on 2 objects.

Hi

There is 2 turrets.

  1. Standart
  2. Laser.

only standart is working.

But when I play with the code and change places of the functions.
the laser is work and the standart no.

Please help.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Turret : MonoBehaviour
{
    private Transform target;
    public float range = 20f;
    public string enemyTag = "Enemy";
    public Transform partToRotate;
    public  float distanceToEnemy;
    public float shortestDistance;
    public float turnSpeed = 10f;
    public float countDown = 1f;
    private float fireRate = 45f;
    public GameObject bulletPrefab;
    public Transform bulletLocation;
    public static int cost = 400;
    public LineRenderer LineRend;
    public bool laser = false;
    // Start is called before the first frame update
    void Start()
    {
        InvokeRepeating("UpdateTarget", 0f, 0.1f);
        shortestDistance = Mathf.Infinity;
    }
    void UpdateTarget()
    {
        target = null;
        GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag);
        GameObject currentEnemy = null;
      
        foreach (GameObject enemy in enemies)
        {
            distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position);
            if (distanceToEnemy < range && currentEnemy == null)
            {
                currentEnemy = enemy;
                target = enemy.transform;
            if (distanceToEnemy > range)
                {
                    target = null;
                }
            
            }
        
        }
      
      
    }
    // Update is called once per frame
    void Update()
    {
        countDown -= 1f / fireRate;
        if (countDown <= 0f)
        {
            Shoot();
            countDown = 2;
        }
        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);
        if (target == null)
        {
            LineRend.enabled = false;
        }
        if (target !=null)
        {
            LineRend.enabled = true;
            LaserShoot();
        }
    }
    void LaserShoot ()
    {
            LineRend.SetPosition(0, bulletLocation.position);
            LineRend.SetPosition(1, target.position);
    }
    void Shoot()
    {
        GameObject BulletGO = (GameObject)Instantiate(bulletPrefab, bulletLocation.position, bulletLocation.rotation);
        Bullet bullet = BulletGO.GetComponent<Bullet>();
            bullet.Seek(target);
            bullet = null;
    }
    void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, range);
    }
}

Not directly related to the question but this line: countDown -= 1f / fireRate; should be made framerate-dependant by multiplying by Time.deltaTime (like this countDown -= 1f / fireRate * Time.deltaTime;).

This whole block should be wrapped in some sort of conditional.

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);

Currently if you don’t have a target it’s going to throw a null reference error since it’s trying to pull from target even if it’s null. So go ahead and put it inside a conditional like if (target) or if (target != null) (they both mean the same thing). I’m guessing right now the laser’s linerenderer isn’t shutting off?

Also how are you differentiating between a turret that is a laser turret and a turret that shoots bullets? Currently it’s trying to run both versions of the turret so if your regular canon doesn’t have a LineRenderer or your laser turret doesn’t have a bulletPrefab you’re gonna run into more null reference errors that will cancel script execution and cause it to not work.

So wrap this chunk of code in a conditional like if (bulletPrefab != null)

countDown -= 1f / fireRate;
        if (countDown <= 0f)
        {
            Shoot();
            countDown = 2;
        }

and this chunk of code in a conditional like if (LineRend != null).

if (target == null)
        {
            LineRend.enabled = false;
        }
        if (target !=null)
        {
            LineRend.enabled = true;
            LaserShoot();
        }