- Home /
2D Top Down Player always look at mouse position
I have a 2D topdown shooter in the works, that's set up on the x and y axis. I'm trying to get my player's character(a spaceship) to always face the mouse so that they coordinate themselves based on where they will be shooting.
I have the code below working almost as intended, but the rotation is inverted based on where the mouse is. For instance, if I move my mouse from 12 to 6 o clock, in a clockwise direction, the ship will rotate counter clockwise at the same time.
mousePos = Input.mousePosition;
objectPos = Camera.main.WorldToScreenPoint(targetPlayer.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
playerRotationAngle = Mathf.Atan2 (mousePos.y,mousePos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler (new Vector3(0,0,playerRotationAngle));
My questions are:
1) What can I change in the transform.rotation z position that can fix this.
2) Is there a better way? I tried using a Raycast, but the ship would rotate on the y axis, instead of the z making movement a nightmare. (as seen in this video:http://www.youtube.com/watch?v=-91SYkWezAM)
mouseX = Input.mousePosition.x;
mouseY = Input.mousePosition.y;
player.LookAt(new Vector3(mouseX,mouseY,0));
You tried this?
Thanks for your reply! Yes, I think that was one of the first things I tried. I thought it would be that simple but when I implement this, the player's sprite points inwards on it's Z axis.
Answer by robertbu · Dec 24, 2013 at 01:31 PM
First, usually when people say "Top Down" they are referring to a camera up in the 'Y' direction looking down on the XZ plane.
As for the code, I see one issue. You use 'targetPlayer.position' in your WorldToScreenPoint(), but you are using target.rotation in the last line. This code will only work if both are the same object. Note I ran a quick test using a default scene and this fix, and the code worked fine.
Beyond that, your setup will have to be the default setup for this code to work. That is, the camera has to be looking towards positive 'z'. If you've reversed the direction the camera is looking, you may be able to fix it by reversing the parameters you pass to Mathf.Atan2().
Also make sure whatever game object you are rotating has a natural vertical orientation. For example Unity's Quad or Sprite will work.
Thanks for your reply! A couple follow up questions for ya.
I did noticed that some other guide do have it oriented in the XZ plane. Is there a plus side to this? I figured it would be easier to just orientate it like a graph and use the Z plane for layering.
targetPlayer will bring back the same object, but I changed it now that you mention it to keep them the same.
I believe you may have found my problem. The camera is looking away from the posZ axis, so I may have to change around my layers in order for it to work.
Why, if you don't $$anonymous$$d me asking, do we need to orientate the sprites vertically?
Thank you so much for your help. I have some last questions to throw at ya.
1) Should I change my project to overall be looking down on the XZ axis?
2) Would LookAt be better for this? It seems like the Euler rotation is overkill, but using LookAt turns the player Sprite inwards on the Z axis barring it's given point to look at.
For a 2D game, the predo$$anonymous$$ate configuration is the XY plane with the the camera looking towards positive 'z'. All the new 2D stuff introduced in Unity 4.3 is based on an XY configuration. A great deal of of the sample code (not top down) you will find on UA assumes a camera looking towards positive 'z'. If you use a different configuration, many folks will have difficulty answering your questions on UA.
Typically for a 2D game on the XY plane, items are displayed either in Unity's semi-new Quad (introduced in Unity 4.1 I think), Unity's Sprite (introduce in Unity 4.3), or on a vertical plane created by either a 3D authoring tool or by the CreatePlane editor script in the wiki. With a plane having a vertical orientation, Transform.LookAt() or Quaternion.LookRotation() won't work...or won't work without a bit of ugly additional rotation code. If you have a horizontal plane, then LookAt() will work, but it may cause you additional problems down the road. It all depend on your game.
There are several ways to do the rotation you've done here, plus your code can be compacted a bit if you like:
#pragma strict
function Update () {
var objectPos = Camera.main.WorldToScreenPoint(transform.position);
var dir = Input.mousePosition - objectPos;
transform.rotation = Quaternion.Euler (Vector3(0,0,$$anonymous$$athf.Atan2 (dir.y,dir.x) * $$anonymous$$athf.Rad2Deg));
}
Thanks for all the great info. You guys really helped me out with this!
Happy Holidays!
Your answer
Follow this Question
Related Questions
Rotation Question in Top-down 3D Game 0 Answers
Rotation on Android vs. PC 0 Answers
Camera Script Rolling on the Z 3 Answers
how do i Limit camera rotation on Y-Axis? 2 Answers
Limiting rotation of object, specifically using scroll wheel 2 Answers