DTD
DTD

Reputation: 11

How would I be able to make a Unity GameObject move fluidly using Translate and IEnumerator?

I am making a simple hoops style game where you throw eggs into a moving birds nest. I am trying to get the nest to move between 2 set positions randomly by translating the GameObject for a set period of time with a vector of random magnitude and direction. When testing my code, the nest jittered in place and the delay only applied at the start of the game.

I think it may have something to do with how the coroutine is being called constantly by the update method, but I can't figure out why this would cause the jittering and how to fix it.

Function code below:

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

public class MoveNest : MonoBehaviour
{
    public bool gameStarted = true;
    public float delay = 4;
    public float nestMoveSpeed = 1;
    public Vector3 nestMoveDirection = Vector3.zero;
    private int zBound = 8;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        if (gameStarted)
        {
            StartCoroutine("ChangeMoveDirection");
            transform.Translate(nestMoveDirection * Time.deltaTime * nestMoveSpeed);
        }
    }

    IEnumerator ChangeMoveDirection()
    {
        yield return new WaitForSeconds(delay);
        float minValue = 0;
        float maxValue = 0;

        if (transform.position.z >= zBound)
        {
            minValue = -10;
            maxValue = 0;

        }
        else if (transform.position.z <= -zBound)
        {
            minValue = 0;
            maxValue = 10;

        }
        else
        {
            minValue = -10;
            maxValue = 10;
        }
        nestMoveDirection = new Vector3(0, 0, Random.RandomRange(minValue, maxValue));

    }

}

I expected the nest to move between 2 set positions randomly on a timed delay. The nest just shook back and forth in testing.

Upvotes: 0

Views: 55

Answers (1)

azelito
azelito

Reputation: 111

The jittering is because you are calling a NEW coroutine on every frame! Each of these coroutines are changing the direction for the object in their own direction.

As I understand it you want to move the object in one direction/distance at first, and in another direction/distance once it reached the first target? You can check if the object has reached the target before calling a new position translate. Getting the new value does not need to be a coroutine:

void Start(){
nestMoveDirection = transform.position;
}

void Update() {
    if (gameStarted && Vector3.Distance(transform.position, targetPosition)<0.1) { //Check for some low number that suits your game scale
        ChangeMoveDirection();
    }
    transform.Translate(nestMoveDirection * Time.deltaTime * nestMoveSpeed);
}

To translate the object for a set amount of time instead of a set distance:

private float delay = 4f;
private float delayTimer;

void Start(){
nestMoveDirection = transform.position;
delayTimer = Time.time;
}

void Update() {
    if (gameStarted && Time.time > delayTimer + delay) {
        delayTimer = Time.time;
        ChangeMoveDirection();
    }
    transform.Translate(nestMoveDirection * Time.deltaTime * nestMoveSpeed);
}

Upvotes: 1

Related Questions