Hi
As the title says, moving/lerping my object leads to super jerky/bumpy movement. I’m not sure exactly why, though I’m new to C# so I know I’ve probably made an egregiously noobish error.
If you’d like to see it, here is a quick ~10 second video: https://drive.google.com/file/d/0Bxh7lmUEfLYYcHNTOFJ2bGZtRlU/view?usp=sharing
Here are the parts of the script that seem to be causing all the trouble:
void FixedUpdate () {
leftScriptPosition = new Vector3 (-1, transform.position.y, transform.position.z);
}
IEnumerator moveLeft(Vector3 leftScriptPosition) {
float t = 0;
while (t < 1) {
t += Time.deltaTime;
transform.position = Vector3.Lerp (transform.position, leftScriptPosition, laneChangeSpeed * Time.deltaTime);
yield return null;
}
}
Thanks heaps 
Use default rigidbody on sphere. Place a plane under a sphere in Z direction.
using UnityEngine;
using System.Collections;
/// <summary>
/// Ball controller.
/// Ball roll in Z+ direction. Tracks change on X axis.
/// </summary>
[RequireComponent(typeof(Rigidbody))]
public class BallController : MonoBehaviour
{
public float acceleration = 1f; // acceleration
public float maxSpeed = 4f; // nax speed
public float jumpPower = 500f; // jump power
public int trackMin = -2; // if -2 it means you can move twice to left [there is 5 tracks if -2 & 2]
public int trackMax = 2; // if 2 it means you can move twice to right [there is 5 tracks if -2 & 2]
public float trackWidth = 2f; // width of the single track
public float trackChangeSpeed = 3f; // how fast transition between tracks
private float _currentSpeed = 0f; // current speed
private int _track = 0; // target track
private bool _onTrack = true; // true if ball is on correct track
private Rigidbody _rb; // rigidbody handler
private Vector3 _spawn; // spawn position, used to keep the x coord
void Start()
{
_rb = GetComponent<Rigidbody>();
_spawn = transform.localPosition;
}
void FixedUpdate()
{
// jump if grounded only [you should use ray casting for detect a ground]
if(_rb.velocity.y <= 0.005f && _rb.velocity.y >= -0.005f)
{
if(Input.GetKey(KeyCode.W))
{
_rb.AddForce(new Vector3(0f, jumpPower, 0f));
}
}
// can change to next track if is on current track only [can not change on track change]
if(_onTrack)
{
// move left
if(Input.GetKey(KeyCode.A))
{
ToLeftTrack();
}
// move right
else if(Input.GetKey(KeyCode.D))
{
ToRightTrack();
}
}
}
void Update()
{
// track change
if(!_onTrack)
{
transform.localPosition = new Vector3(Mathf.MoveTowards(transform.localPosition.x, _spawn.x + _track * trackWidth, Time.deltaTime * trackChangeSpeed), transform.localPosition.y, transform.localPosition.z);
if(transform.localPosition.x == (_spawn.x + _track * trackWidth))
{
_onTrack = true;
}
}
// increase a speed & move
_currentSpeed = Mathf.MoveTowards(_currentSpeed, maxSpeed, Time.deltaTime * acceleration);
transform.position = new Vector3(transform.position.x, transform.position.y, transform.position.z + _currentSpeed * Time.deltaTime);
}
void ToLeftTrack()
{
if(_track > trackMin)
{
_track--;
_onTrack = false;
}
}
void ToRightTrack()
{
if(_track < trackMax)
{
_track++;
_onTrack = false;
}
}
}