Hi. When my player moves forward, it keeps jittering, going faster and slower.

I’m trying to get my player (car) to move towards the right junction of a road according to user Input: left, forward or right. I’ve tried several different solution but all have the same effect. Anyone know why?

Junction:

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

public class JunctionSys : MonoBehaviour
{
    
    [SerializeField] public Transform NorthJunction;
    [SerializeField] public Transform EastJunction;
    [SerializeField] public Transform SouthJunction;
    [SerializeField] public Transform WestJunction;

    [Space]

    public GameObject North;
    public GameObject East;
    public GameObject South;
    public GameObject West;

    [Space]

    public CarSystem player;
    public string nextName;
    public bool turnable;

    [Space]

    [SerializeField] public Transform target;


    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    void OnTriggerEnter(Collider other)
    {
    	if(other.gameObject.CompareTag("Player"))
    	{
    		turnable = true;
    	}
    }

    void  ChooseDirection()
    {
    	if(target == NorthJunction)
    	{
    		nextName = "N";
    	}
    	if(target == EastJunction)
    	{
    		nextName = "E";
    	}
    	if(target == SouthJunction)
    	{
    		nextName = "S";
    	}
    	if(target == WestJunction)
    	{
    		nextName = "W";
    	}

    	player.Restart();
    }

    public void Forward()
    {
    	if(turnable == true)
    	{
	    	if(player.GoingNorth == true && North != null)
	    	{
	    		target = NorthJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingEast == true && East != null)
	    	{
	    		target = EastJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingSouth == true && SouthJunction != null)
	    	{
	    		target = SouthJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingWest == true && WestJunction != null)
	    	{
	    		target = WestJunction;
	    		ChooseDirection();
	    	}
    	}
    }

    public void Right()
    {
    	if(turnable == true)
    	{
	    	if(player.GoingNorth == true && EastJunction != null)
	    	{
	    		target = EastJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingEast == true && SouthJunction != null)
	    	{
	    		target = SouthJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingSouth == true && WestJunction != null)
	    	{
	    		target = WestJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingWest ==  true && NorthJunction != null)
	    	{
	    		target = NorthJunction;
	    		ChooseDirection();
	    	}
    	}
    }

    public void Left()
    {
    	if(turnable == true)
    	{
	    	if(player.GoingNorth == true && WestJunction != null)
	    	{
	    		target = WestJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingEast == true && NorthJunction != null)
	    	{
	    		target = NorthJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingSouth == true && EastJunction != null)
	    	{
	    		target = EastJunction;
	    		ChooseDirection();
	    	}
	    	if(player.GoingWest == true && SouthJunction != null)
	    	{
	    		target = SouthJunction;
	    		ChooseDirection();
	    	}
    	}
    }


}

Car:

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

public class CarSystem : MonoBehaviour
{
    public bool GoingNorth;
    public bool GoingSouth;
    public bool GoingEast;
    public bool GoingWest;

    [Space]

    public JunctionSys junction;
    public JunctionSys nextJunction;
    public JunctionSys startJunction;

    [Space]

    public Transform Aim;
    public Transform Player;
    public Transform startJunctionObj;

    [Space]
    [Space]

    public bool drive;
    public float speed = 15f;
    public float turnSpeed = 1f;
    
 

    void Start()
    {
        
    }

    // Update is called once per frame
    void LateUpdate()
    {
        if(drive == true)
        {
        	var step = speed * Time.deltaTime;
        	Player.transform.position = Vector3.MoveTowards(transform.position, Aim.transform.position, step);

            /*var step = speed * Time.deltaTime;
            var movePos = Vector3.Lerp(transform.position, Aim.transform.position, 0.125f);
            Player.transform.position = Vector3.MoveTowards(transform.position, movePos, step);*/

            /*Vector3 targetDirection = Aim.position - transform.position;
            float singleStep = turnSpeed * Time.deltaTime;
            Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, singleStep, 0.0f);
            transform.rotation = Quaternion.LookRotation(newDirection);*/

            Vector3 direction = Aim.position - transform.position;
            Quaternion rotation = Quaternion.LookRotation(direction);
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, turnSpeed * Time.deltaTime);
        }
    }

    public void Startup()
    {
    	Aim = startJunctionObj;
    	junction = startJunction;
    	drive = true;
    	GoingNorth = true;
    }


    void OnTriggerEnter(Collider other)
    {
    	if(other.gameObject.CompareTag("junction"))
    	{
    		drive = false;
    	}
    }

    public void Restart()
    {
    	
    	if(junction.nextName == "N")
    	{
    		Aim = junction.NorthJunction;
            nextJunction = junction.North.GetComponent<JunctionSys>();
            ChangeGoing("N");
    	}
    	if(junction.nextName == "E")
    	{
    		Aim = junction.EastJunction;
            nextJunction = junction.East.GetComponent<JunctionSys>();
            ChangeGoing("E");
    	}
    	if(junction.nextName == "S")
    	{
    		Aim = junction.SouthJunction;
            nextJunction = junction.South.GetComponent<JunctionSys>();
            ChangeGoing("S");
    	}
    	if(junction.nextName == "W")
    	{
    		Aim = junction.WestJunction;
            nextJunction = junction.West.GetComponent<JunctionSys>();
            ChangeGoing("W");
    	}


    	Debug.Log(junction.nextName);
        junction = nextJunction;
    	drive = true;
    }

    public void Fwrd()
    {
    	junction.Forward();
    }
	public void Lft()
    {
    	junction.Left();
    }
    public void Rit()
    {
    	junction.Right();
    }

    void ChangeGoing(string dir)
    {
        switch(dir)
        {
            case "N":
                GoingNorth = true;
                GoingEast = false;
                GoingSouth = false;
                GoingWest = false;
                break;

            case "E":
                GoingNorth = false;
                GoingEast = true;
                GoingSouth = false;
                GoingWest = false;
                break;

            case "S":
                GoingNorth = false;
                GoingEast = false;
                GoingSouth = true;
                GoingWest = false;
                break;

            case "W":
                GoingNorth = false;
                GoingEast = false;
                GoingSouth = false;
                GoingWest = true;
                break;
        }
    }
}

I’ve seen a lot of code over the years - instead of searching for the issue here, i’d really really suggest to just rewrite this.

I can promise you that it can be written with at max 1/4th of the length.

Start with removing your booleans:

 public bool GoingNorth;
 public bool GoingSouth;
 public bool GoingEast;
 public bool GoingWest;

instead create an enumeration:

 public enum Direction {North, East, South, West}
 public Direction CurrentDirection;

Then you can scrap the complete ChangeGoing function and remove all “E”, “W”… string and instead directly set the direction by the enumeration value.

then you should be able to remove the complete ChooseDirection function and instead directly call player.Restart() as you can then instead of checking which nextName has been chosen can access the target of the junction.

In the same manner you should reevaluate your complete code if possible. If you write everything 4 times for east, west, north, south you will slowly become insane over time.

When the code is slimmed down it will be easier to see what you are actually doing.

To then properly debug the issue i’d suggest you add some debug logs to your OnTriggerEnter functions as those seem to be something that might trigger at wrong times or more times than you think they do.

Actually when I was rewriting the code, I noticed that it still did the same thing (a bit less pronounced thought) with just this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CarSys2 : MonoBehaviour
{
    public bool drive;

    public enum Direction {North, East, South, West}
    public Direction CurrentDirection;

    public Transform startJunctionTrans;
    public Transform Aim;

    [Space]

    public JunctionSys2 startJunction;

    [Space]

    public float speed = 10.0f;



    void OnTriggerEnter(Collider other)
    {
        if(other.gameObject.CompareTag("junction"))
        {
            drive = false;
        }
    }


    public void Startup()
    {
        CurrentDirection = Direction.North;
        Aim = startJunctionTrans;
        drive = true;
    }





    void Update()
    {
        if(drive == true)
        {
            var step = speed * Time.deltaTime;
            var movePos = Vector3.Lerp(transform.position, Aim.transform.position, 0.125f);
            transform.position = Vector3.MoveTowards(transform.position, movePos, step);
        }
    }

}

Is maybe the jittering caused by the car being too far way from the game origin (x ,y, z ) ? because all coordinates are single floating point numbers thus with limited precision. If this is the case, then jittering should not occur when your car is close to the game origin.