Vector3.MoveTowards and Quaternion.RotateTowards

Hello all –

I’ve got an interesting situation. I’m making a game where the player is able to move objects back along a path that the object has traveled, including its rotation.

The trick is that I would like to do these at the same rate without having the nice spline curve… I want all movement to be linear.

Vector3.MoveTowards has been working for me, but I’m having trouble getting the Quaternion.RotateTowards to do it at the same rate.

Anyone have any suggestions?

I don’t know exactly what you’re doing, but suppose that you have an array of positions/rotations and want the object to move at constant speed and rotate smoothly from point to point. If that’s true, I suggest you to use Quaternion.Slerp and Vector3.Lerp instead: since both are controlled by a float value between 0 and 1, they will always stay in sync. In order to keep a constant speed, calculate the movement duration and vary the control variable at suitable rate.

Supposing that you want to move from pointA to pointB and rotate from rotA to rotB at the same time, you could use something like this:

var moveSpeed: float = 5;

private var moving = false;

function MoveFromTo(pointA: Vector3, pointB: Vector3, rotA: Quaternion, rotB: Quaternion){
  moving = true; // it's moving now
  var dist = Vector3.Distance(pointA, pointB); // find the distance to travel
  var duration = dist / moveSpeed; // calculate the movement duration
  var t: float = 0; // t is the control variable
  while (t < 1){
    t += Time.deltaTime / duration; // t varies at calculated rate
    transform.position = Vector3.Lerp(pointA, pointB, t); // move...
    transform.rotation = Quaternion.Slerp(rotA, rotB, t); // and rotate
    yield; // let Unity free till next frame
  }
  moving = false; // movement finished
}

The boolean variable moving is true while the object moves: when it becomes false, you can pass to the next point. In the example below, pos and rot are the positions and rotations arrays, and setting moveBack to true makes the object move back to the first position:

var pos: Vector3[]; // positions array
var rot: Quaternion[]; // rotations array
var moveBack = false; // true to make move back
var curPos: int = 0;

function Update(){
  // if must moveBack and isn't at the first position...
  if (moveBack && curPos > 0){
    if (moving) return; // do nothing while moving
    var nxtPos = curPos - 1; // find the next position
    MoveFromTo(pos[curPos], pos[nxtPos], rot[curPos], rot[nxtPos]);
    curPos--;
  }
}