This code will force a box to rotate then as it rotates moves. But it's not the effect that I want. I want it to rotate towards the object then move in that direction.
Trying to accomplish a rotation first then move. So let's say a cube gets to a waypoint then i want the cube to rotate towards the next way point then move . Instead I'm getting a loop-a-around effect.
What happens here is that (assuming you're doing this in Update()), every frame the rotation changes a little bit and the position changes a little bit.
The easiest way to do this would be to delay the move until the rotation is done. Here's an elegant way of doing this:
var targetRotation: Quaternion;
var moveSpeed: float; // set in inspector
var turnSpeed: float; // set in inspector
var target: Transform; // assumes target is set, through inspector or scripting
function Start() {
turnSpeed *= Time.fixedDeltaTime;
moveSpeed *= Time.fixedDeltaTime;
}
function Update() {
if (Input.GetButtonDown(0)) { // do the movement on mouse click for now
targetRotation = Quaternion.LookRotation(target.position - transform.position);
DoTransition();
}
}
function DoTransition() {
while (transform.rotation != targetRotation) {
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed);
yield;
}
/* use this if the above gives you issues - in case rotation isn't 100% accurate
while (Quaternion.Angle(transform.rotation, targetRotation) > 1) {
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed);
yield;
}*/
MoveToTarget();
}
function MoveToTarget() {
while (transform.position != target.position) {
transform.position = Vector3.MoveTowards(transform.position, target.position, moveSpeed);
yield;
}
}
By throwing `yield;` into the two functions, I'm telling them to suspend (essentially) the loops until other functions have had time to run. This keeps them from holding up the rest of the game. You can try without the yields but I recommend saving the project first as it can have some unexpected results if not done right.
Notice, that I'm only doing this whole thing once (in this case on a mouse click), because the game will continue calling Update meantime, and it simply creates a separate instance of the function. If you need more flexiblity in ensuring the transition doesn't happen more than needed, keep a boolean named isInTransition or something that you can use to check before starting a new transition.
If you need to do more calculations before the rotation you can make it a tad prettier like this:
function DoTransition() {
// do some stuff
yield StartCoroutine(RotateToTarget());
MovetoTarget();
}