How to dynamically set transform positions (for a Bezier curve)?

Hey everyone, I’m remaking a level from Mega Man 2 and I’m having trouble with this dog enemy. I have the dog which instantiates a certain number of fireballs every couple of seconds which seems to be working, but I seem to have messed up the fireball movement. The movement is supposed to be parabolic, so I tried using a three-point Bezier curve. The three points for the curve are attached to the dog (cause if I duplicate the dog I wanted the points to move with the new dog), the fireballs spawn, but I don’t know how to set these point so that the fireballs can follow them. Any help is appreciated!

Fireball movement code:

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

public class Fireball : MonoBehaviour {

    [Header("Set in Inspector")]
    public float duration = 1f;                      // the number of seconds for the lerp

    [Header("Set Dynamically")]
    public float timeStart;
    public Transform p0;
    public Transform p1;
    public Transform p2;

    private void Start()
    {
        timeStart = Time.time;
    }

    void Update ()
    {
        float u = (Time.time - timeStart) / duration;
        u = u % 1f;                                                     // make sure u is always between 0 and 1
        Vector2 p01 = (1 - u) * p0.position  + u * p1.position;
        Vector2 p12 = (1 - u) * p1.position + u * p2.position;
        Vector2 p012 = (1 - u) * p01 + u * p12;
        transform.position = p012;
    }
}

Dog Controller code:

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

public class DogController : MonoBehaviour {

    [Header("Set in Inspector")]
    public Transform fireballSpawnPoint;
    public GameObject fireballPrefab;
    public float timeBetweenShots = 1.5f;

    private float ranVal;
	
	void Start ()
    {
        Invoke("FireShoot", timeBetweenShots);                          // first fireball shot from the dog
	}
	
    void FireShoot()
    {
        ranVal = Random.value;

        if (ranVal <= 0.33)
        {
            StartCoroutine(ShootThree());
            Invoke("FireShoot", timeBetweenShots);                          // first fireball shot from the dog
        }
        else if (ranVal > 0.33 && ranVal < 0.66)
        {
            StartCoroutine(ShootSix());
            Invoke("FireShoot", timeBetweenShots);                          // first fireball shot from the dog
        }
        else
        {
            StartCoroutine(ShootNine());
            Invoke("FireShoot", timeBetweenShots);                          // first fireball shot from the dog
        }
    }
	
	IEnumerator ShootThree()
    {
        for (int i = 0; i < 3; i++)
        {
            Instantiate(fireballPrefab, fireballSpawnPoint.position, Quaternion.identity);
        }
        yield return new WaitForSeconds(1);
    }

    IEnumerator ShootSix()
    {
        for (int i = 0; i < 6; i++)
        {
            Instantiate(fireballPrefab, fireballSpawnPoint.position, Quaternion.identity);
        }
        yield return new WaitForSeconds(1);
    }

    IEnumerator ShootNine()
    {
        for (int i = 0; i < 9; i++)
        {
            Instantiate(fireballPrefab, fireballSpawnPoint.position, Quaternion.identity);
        }
        yield return new WaitForSeconds(1);
    }
}

Well since you instantiate your prefab dynamically you have to set the transform references when you instantiate them. To do that you should change some things. First of all since your fireball prefab has the Fireball script attached, it would make more sense to declare your prefab variable like this:

public Fireball fireballPrefab;

instead of

public GameObject fireballPrefab;

That way you don’t need to do a GetComponent when instantiating the prefab. To set the transforms you would simply do:

Fireball fb = Instantiate(fireballPrefab, fireballSpawnPoint.position, Quaternion.identity);
fb.p0 = yourTransform0;
fb.p1 = yourTransform1;
fb.p2 = yourTransform2;

If you don’t want to change the prefab variable type you would need to do this:

GameObject go = Instantiate(fireballPrefab, fireballSpawnPoint.position, Quaternion.identity);
Fireball fb = go.GetComponent<Fireball>();
fb.p0 = yourTransform0;
fb.p1 = yourTransform1;
fb.p2 = yourTransform2;

Though i would highly recommend to change the variable type (don’t forget to reassign the prefab).

It also seems strange that you made 3 coroutines but you actually don’t need any coroutine features. This just creates garbage. At the moment you could simply replace your coroutine with normal methods. Also the 3 methods do exactly the same thing, just spawn a different fireball count. So you may want to consider using a single method / coroutine and pass the fireball count as parameter.

I might be missing something, because you mentioned bezier curve. A quick search on Bezier Curves gives you the info you need to get the points along a bezier curve.