Shooting Projectiles from different positions in the world of the same Prefab

Hello,

I’m creating a tower defence prototype and I have different towers that can be placed from it’s spawn point.
Towers start shooting enemies as soon as they enter in the tower range.
The problem I’m facing is When I place a single instance of a tower type things work fine.

9736351--1392502--upload_2024-3-29_8-2-17.png

But as soon as I place another instance of the same tower. The towers start shooting from a random point in the world.

9736351--1392508--upload_2024-3-29_8-3-39.png

How can I fix this? Let me know if I need to provide any other info.
Attaching the code below for projectile movement.

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

public class Projectile : MonoBehaviour
{
    [SerializeField] float velocity;
    [SerializeField] float angle;

    Transform shootPointRef;
    Vector3 hitPoint;

    GetTarget getTarget;

    private void OnEnable()
    {
       
    }

    // Start is called before the first frame update
    void Start()
    {
        getTarget = FindObjectOfType<GetTarget>();
       
    }

    private void Update()
    {
        float _Angle = angle * Mathf.Deg2Rad;
        float time = 0f;

        hitPoint = GetHitPoint(getTarget.transform.position, Vector3.zero, transform.position, velocity, out time);

        Vector3 initialVelocity = hitPoint - GetShootPointPosition();
        // StopAllCoroutines();
        StartCoroutine(CalculateVelocity(initialVelocity, velocity, _Angle));
    }

    private Vector3 GetShootPointPosition()
    {
        return getTarget.GetComponentInParent<Tower>().ShootPoint.position;
    }

    private IEnumerator CalculateVelocity(Vector3 direction, float iVelocity, float iAngle)
    {
        float t = 0;
        while (t < 100f)
        {
            float x = iVelocity * t * Mathf.Cos(iAngle);
            float y = iVelocity * t * Mathf.Sin(iAngle) - (1f/2f) * -Physics.gravity.y * Mathf.Pow(t, 2);
            Vector3 position = GetShootPointPosition() + (-direction * x) + new Vector3(0, 1, 0) * y;

            float tFactor = Vector3.Distance(GetShootPointPosition(), hitPoint) / velocity;

            transform.position = position + ((tFactor ) * Vector3.one);

            t += Time.deltaTime;
            yield return null;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if(other.CompareTag("Enemy"))
        {
            Debug.Log("Ready to Destroy");
            Destroy(gameObject);
          
        }
    }

    Vector3 GetHitPoint(Vector3 targetPosition, Vector3 targetSpeed, Vector3 attackerPosition, float bulletSpeed, out float time)
    {
        Vector3 q = targetPosition - attackerPosition;
        //Ignoring Y for now. Add gravity compensation later, for more simple formula and clean game design around it
        q.y = 0;
        targetSpeed.y = 0;

        //solving quadratic ecuation from t*t(Vx*Vx + Vy*Vy - S*S) + 2*t*(Vx*Qx)(Vy*Qy) + Qx*Qx + Qy*Qy = 0

        float a = Vector3.Dot(targetSpeed, targetSpeed) - (bulletSpeed * bulletSpeed); //Dot is basicly (targetSpeed.x * targetSpeed.x) + (targetSpeed.y * targetSpeed.y)
        float b = 2 * Vector3.Dot(targetSpeed, q); //Dot is basicly (targetSpeed.x * q.x) + (targetSpeed.y * q.y)
        float c = Vector3.Dot(q, q); //Dot is basicly (q.x * q.x) + (q.y * q.y)

        //Discriminant
        float D = Mathf.Sqrt((b * b) - 4 * a * c);

        float t1 = (-b + D) / (2 * a);
        float t2 = (-b - D) / (2 * a);

        //Debug.Log("t1: " + t1 + " t2: " + t2);

        time = Mathf.Max(t1, t2);

        Vector3 ret = targetPosition + targetSpeed * time;
        return ret;
    }
}

And here’s Shoot functions that is being called in the tower script.

What is the purpose of using TransformPoint in the Shoot function?
shootPoint.position gives you the world position of shootPoint. You instantiate the bullet and give it that world position.
It also not needed to parent the bullet to the tower. It also doesn’t make sense to name a Vector3 a “transform”, it will just cause confusion for you.

Vector3 bulletPosition = shootPoint.position;
GameObject bullet = Instantiate(projectile, bulletPosition, Quaternion.identity);

You could let Unity’s physics engine move your projectiles and then the only function you’ll need in your projectile script is OnCollisionEnter.

Currently your projectile script is starting an unnecessary coroutine in every Update. Instead you could calculate a projectile’s launch velocity to move along a trajectory in a few lines of code without the need for any iteration.

Sometimes it’s understandable that somebody would want to avoid the physics engine if their game’s movement is so simplistic that they feel their own code would be more performant. But I don’t think this applies here.