Using LookAt on my player sprite whilst rotating a main camera that follows the sprite in 2.5D and using WASD control

WASD and arrow keys are used for the movement. Clicking on the ground also moves the player to a location, which works fine enough for now. The main camera is set up in a default manner and NOT as a child of the player object. The script for the camera rotates the camera around (what must eventually be) a 2D player sprite with the camera at a 2.5D isometric angle, following the player at a fixed distance/offset/angle. After going through some hectic learning about euler angles, the rotation script for the camera works too, which I could post here, but it doesn’t seem relevant. It works, and I don’t need to change that particular method. Pressing ‘Q’ or ‘E’ rotate the camera 45 degrees in their respective directions. If you’ve played “Don’t Starve” basically these are the same controls I’m trying to replicate.

Suffice, my main camera uses “LookAt” in its scripted component. If I use a “LookAt” component again in my player script it seems to screw up all my WASD control scripting even though it’s supposed to be in relation to the main camera.

For example, when I write the following in C# script:

if (Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.UpArrow)) {
	// ...
Vector3 cameraForwardLine = Camera.main.transform.forward;
cameraForwardLine.y = 0f;
transform.Translate(Camera.main.transform.forward * Time.deltaTime * wasdSpeed);
}

This will work fine without my “LookAt” sprite component script enabled on the player sprite. Everything I’ve tried to get the sprite to constantly look at the camera while the camera rotates (at 45 degree increments) around and follows the player has resulted in not backwards WASD and arrow key movement but alterations in movement depending on the camera’s current rotation. What’s going on? “LookAt” on my player sprite isn’t working. My basic “LookAt” component class attached to my prototype player sprite (a flattened capsule in this case) in C# looks like this (which does get the player sprite facing the camera but messes up the WASD control):

public class LookAtCameraOnOneAxis : MonoBehaviour {
	void Update () {
		Vector3 groundLevelCameraLine = Camera.main.transform.position;
		groundLevelCameraLine.y = 0f;
		transform.LookAt(groundLevelCameraLine, ...[?]);
	}
}

For one thing I don’t really know what my “WorldUp” parameter should be in this case. I’ve tried Vector3.up and -Vector3.up (for some reason -Vector3.up has been recommended when doing billboards apparently). I’ve also tried not adding a WorldUp parameter, which also doesn’t work. All three basically do the same thing. Forward pressing W is at first back, which almost makes sense if it were straight back. But the player sprite sinks halfway into the ground and looks to steady out moving back. And S swings the sprite up gracefully into the air and steadies out once the sprite is laying completely horizontal and traveling upward. Each rotation of the camera affects the movement differently with this LookAt script enabled too. But after rotating the camera 45 degrees, W is diagonal back, then W is left/right… Perhaps unnecessarily I’m just describing the messed up behavior here.

To simplify, if I disable this LookAt script on the player object my WASD control works as expected currently, along with everything else already scripted. With the sprite LookAt component disabled, forward is forward with respect to the camera no matter what the rotation of the camera just that my player sprite looks in a fixed direction and not at the camera.

My question is basically, can I use this LookAt function to do what I want on the player sprite, is there an easy fix for this, or am I going to have to write a new algorithm myself somehow without using LookAt on my player sprite… ? Thanks in advance if anyone helps out.

Perhaps this should have been in Forums instead of Answers. I haven’t completely figured out this puzzle just yet. But to wrap this Answer up, my player sprite is actually at coordinate 1 and not 0 on the y axis. I went ahead and included the LookAt in my movement script. It’s written like this:

	void Start () {
		myTransform = transform;							// sets myTransform to this GameObject.transform

	}
	
	void Update () {
		Vector3 groundVectorOfCamera = Camera.main.transform.position;
		groundVectorOfCamera.y = 1f;
		myTransform.LookAt (groundVectorOfCamera, Vector3.up);

...

        }

…points the player sprite’s LookAt function completely level with the horizon. Because LookAt turns the sprite toward the camera, ‘W’ needs to articulate forward in the inverse, like so:

		if (Input.GetKey (KeyCode.W) || Input.GetKey (KeyCode.UpArrow)) {
			Vector3 cameraForwardLine = Camera.main.transform.forward;
			cameraForwardLine.y = 0f;
			transform.Translate(-(cameraForwardLine) * Time.deltaTime * wasdSpeed);
		}

Here, the forward from the initial camera position needs to be inverse for my code. Although upon rotation (in 45 degree increments) in my case the Camera.main.transform.forward also rotates 45 degrees extra for some reason. For example if I press ‘Q’ to rotate right 45 degrees, then ‘W’ will move the player sprite diagonally right at a 45 degree angle from that rotation, and another 45 degree rotation will cause ‘W’ to move the sprite right. This is actually predictable behavior, so I guess I can compensate for it. But being new to Unity I’ll have to puzzle over it for awhile. Regardless, the following is the basic “Billboarding” sample code found on the Wiki for anyone else looking to replicate similar player movement.

Billboarding Sprites to LookAt a Target