Rotating 2D object on Y-axis to face moving direction

Hey guys, I’m trying to recreate the 2D Controller on my own (mainly because I want to fully understand why it does what it does). Unfortunately, my first few attempts failed miserably, so I grabbed the Controller.Move code from the docs.

Here’s what I have so far:

var speed = 6.0;
var jumpSpeed = 8.0;
var gravity = 20.0;

private var moveDirection = Vector3.zero;

function Awake(){
	transform.TransformDirection (Vector3.forward);
	//transform.Rotate(0, 90, 0);
}
function FixedUpdate() {
	var controller : CharacterController = GetComponent(CharacterController);
	if (controller.isGrounded) {
		
		// We are grounded, so recalculate
		// move direction directly from axes
		moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, 0);
		moveDirection = transform.TransformDirection(moveDirection);
		moveDirection *= speed;
		
		if (Input.GetButton ("Jump")) {
			moveDirection.y = jumpSpeed;
		}
	}
	
	// Apply gravity
	moveDirection.y -= gravity * Time.deltaTime;
	// Move the controller
	controller.Move(moveDirection * Time.deltaTime);
	animation.CrossFade("walk");
	
}

This works fine when I move the character – that is, he moves along the X-axis (either left or right) when I hit the arrow keys, and he jumps when I hit the jump key. The problem is that he won’t rotate to face whichever direction he’s moving in.

I’ve scanned the boards a bunch of times, Googled to see if any of the bloggers have addressed this, analyzed the PlayerPlatformController from the 2D tutorial, and tried various other things to try and make it simply turn around and face the direction in which it’s moving. Unfortunately, I still can’t get it.

I wanna say that I have to use some form of Quaternion.LookRotation(), but that’s not working, either. Any time I try and adjust the rotation, my model starts bouncing around or spinning around uncontrollably. I just want it to rotate and face the direction in which it’s moving.

Any suggestions? Any help and/or explanations would be much appreciated.

Thanks[/code]

This will rotate to look at a target object, but only apply the rotation to the Y axis of the object you attach the script to.

public class RotateToLookAt : MonoBehaviour 
{ 
   #region Public Properties 
   public float rotateSpeed = 0.1f; 
   public GameObject target; 
   #endregion 


   #region Events 
   /// <description> 
   ///    Runs on frame update 
   /// </description> 
	private void Update() 
	{ 
		// Store the rotation before anything changes. 
		Quaternion srcRot = transform.rotation; 

		// Get a vector towards the target for a new Quaternion oriented to 'lookAt' target. 
		Vector3 directionToTarget = target.transform.position - transform.position; 

		// Set the 'altitude' to be equal so we stay on a XZ plane relative to the turret
		directionToTarget.y = transform.position.y;

		Quaternion dstRot = Quaternion.LookRotation(directionToTarget, transform.up); 

		// Rotate by <this.rotateSpeed>% 
		Quaternion slerpedRot = Quaternion.Slerp(srcRot, dstRot, this.rotateSpeed); 
			 
		// Only use the Eular Y data from the slerp
		transform.eulerAngles = new Vector3(srcRot.eulerAngles.x, 
													slerpedRot.eulerAngles.y, 
													srcRot.eulerAngles.z); 
	} 

   #endregion 
}

To make this work for your needs, you should be able to just replace the Vecotr3 ‘directionToTarget’ with your direction of movement.

Hope this helps. I’m sure there are other ways to do it, but this seems standard. I’ve been cautioned against using slerp on too many objects, but a dozen, or 1 in the case of your player controller, should be unnoticeable. Please let me know if you learn anything different.

Cheers,