Make GameObject look at one target on x/z axis and another on y axis

Hello,

I’ve spend the last hours looking for a solution and tried different approaches without success. Now I’m very much at the end of the line and can’t wrap my head around the problem anymore. A little push in the right direction would be appreciated.

What I’m trying to do: I’m working on a small project implementing a rts-type control scheme. The Player should be able to order Objects around, but not on a flat plane but on the surface of a sphere. Objects need not stick to the sphere, but move freely around it to get to their target position. This works fine so far.

Now, for cosmetic reasons, I want the objects to look toward the waypoint on two axis, but to the center of the sphere on the third, so that they are more or less upright relative to the sphere. In flight terms: The Object pitch and yaw should be in the direction of the waypoint, its roll in the direction of the spheres center (http://en.wikipedia.org/wiki/Flight_dynamics#mediaviewer/File:Rollpitchyawplain.png).

Here is the last working state of my script:

void Update () {

	if (waypointsList.Count > 0) {

		//Find Vector to the Waypoint
		Vector3 VectorToWayPoint = waypointsList[0] - transform.position;

		Debug.DrawLine(new Vector3(0,0,0), waypointsList[0], Color.yellow);
		Debug.DrawLine(new Vector3(0,0,0), transform.position, Color.green);

		//Get intermediate Waypoint
		Vector3 VectorIntermediateWayPoint = (waypointsList[0] - transform.position)*.1f + transform.position;
		Debug.DrawLine(transform.position, VectorIntermediateWayPoint, Color.blue);

		//How far is the intermediate Waypoint along the route?
		float DistanceToRoute = Vector3.Distance(transform.position, VectorIntermediateWayPoint)/Vector3.Distance(transform.position, waypointsList[0]);

		//Get Distance from World Center at Intermediate WayPoint
		float DistanceFromCenter = Mathf.Lerp(Vector3.Distance(ZeroVector, transform.position), Vector3.Distance(ZeroVector, waypointsList[0]), DistanceToRoute);

		//Normalize the intermediate Waypoint and push it out by interpolated distance
		VectorIntermediateWayPoint = Vector3.Normalize(VectorIntermediateWayPoint)*DistanceFromCenter;

		Debug.DrawLine(new Vector3(0,0,0), VectorIntermediateWayPoint, Color.red); 

		//Move the ship
		transform.position = Vector3.MoveTowards(transform.position, transform.position + transform.forward, 7.0F*Time.deltaTime);

		//Turn the ship
		Vector3 targetLookDirection = VectorIntermediateWayPoint - transform.position;
		Vector3 newLookDirection = Vector3.RotateTowards(transform.forward, targetLookDirection, 1.0F*Time.deltaTime, .0F);

		transform.rotation = Quaternion.LookRotation(newLookDirection);

		if (Vector3.Distance(transform.position, waypointsList[0]) < .5F) {
			waypointsList.RemoveAt(0);
		}
	}
}

Thank you very much!

Edit:

transform.LookAt(Waypoint, VectorAwayFromCenter) makes the object behave like I want, but there isn’t an option to turn gradually over time with it, is there?

Oh boy…

Ok, I figured it out somehow.

If anybody has the same problem, here is my solution:

			Vector3 targetDirection = VectorIntermediateWayPoint - transform.position;
			Vector3 newDirection = Vector3.RotateTowards(transform.forward, targetDirection, turnRate*Time.deltaTime, .0f);

			transform.LookAt(transform.position + newDirection, transform.position - ZeroVector);

Where ZeroVector is the position of the spheres center, in this case (0,0,0).

Edit: If anybody has a more elegant and versatile solution, I’d be happy to hear about it.