0
votes

I'm making a small game in Unity and part of it it's that glass balls spawn every few seconds and they follow a path composed of targets, and the prefab has these targets specified:

Prefab picture

And here is the code:

public class move_to_target : MonoBehaviour
{
    public GameObject[] target;

    public float speed;

    int current = 0;

    float radius_target = 1;

    // Update is called once per frame
    void Update()
    {
        if (Vector3.Distance(target[current].transform.position, transform.position) < radius_target)
        {
            current = Random.Range(0, target.Length);
            if (current >= target.Length)
            {
                current = 0;
            }
        }
        transform.position = Vector3.MoveTowards(transform.position, target[current].transform.position, Time.deltaTime * speed);
    }
}

So, whenever the ball spawns, it should go for the 1st target, then 2nd and finally the 3rd, but when I load the game, all the balls go to the horizon without stopping.

The problem seems to solve itself when I put the ball/fairy prefab in the scene and load the targets in the scene instead of the prefabs but that isn't the ideal solution.

How can I make it so the balls go to the targets in the scene?

2

2 Answers

0
votes

Don't have enough rep to comment but this looks like it should work, what do you see if you Debug.Log(target[current].transform.position)?

If you don't need the target game object references, you could store Vector3[]'s instead.

0
votes

A couple of things: You're randomizing your target every single update frame, so there is actually no progression from one target to the next in any kind of order. Is that intentional?

Also, you're moving the ball transform only when its distance is less than (<) a certain value. It seems more likely that you should be moving the ball as long as its distance is greater than (>) that value. Are you trying to go from a distance of greater than 1, to a distance of less than / equal to one?

If that's the case, maybe something like (untested):

public List<Transform> target = new List<Transform>();

    public float speed;

    int current = 0;

    float radius_target = 1;

void Update()
    {
        if (Vector3.Distance(target[current].transform.position, transform.position) > radius_target)
        {
            transform.position = Vector3.MoveTowards(transform.position, target[current].transform.position, Time.deltaTime * speed);
        } else {
            current++;
            if (current == target.Count)
            {
                current = 0;
            }
        }
    }

But by this method the ball will seek to return to target[0] after target[2] (or whatever is the last one) and keep going forever in a loop. If you want to stop after reaching the last target you'd want to only execute this whole block if the current target < target.Count without returning to zero as it currently does.

And finally, your radius threshold of 1 could either work or not work, depending on how these targets are set up in the scene. This whole approach only works if they are all more than one unit (or radius_target units) away from each other.