Reputation: 11
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
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