- Home /
Rotate object/weapon towards mouse cursor 2d.
I wouldn't think this to be difficult, but apparently it is. I've tried multiple functions (LookAt, Rotate, etc.) and cannot figure out the correct order to get my weapons to always point towards mouse cursor. It is a 2d game, side view shooter. Very similar to crash commandos http://www.youtube.com/watch?v=4bO80FvD2Xs . Need objects to rotate around the z axis and when mouse is clicked a fires towards cursor. Any help or links would be appreciated.
Answer by Dusk · Jun 14, 2011 at 08:40 PM
Here. This should work.
var mouse_pos : Vector3;
var target : Transform; //Assign to the object you want to rotate
var object_pos : Vector3;
var angle : float;
function Update ()
{
mouse_pos = Input.mousePosition;
mouse_pos.z = 5.23; //The distance between the camera and object
object_pos = Camera.main.WorldToScreenPoint(target.position);
mouse_pos.x = mouse_pos.x - object_pos.x;
mouse_pos.y = mouse_pos.y - object_pos.y;
angle = Mathf.Atan2(mouse_pos.y, mouse_pos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(Vector3(0, 0, angle));
}
Basically, I just get the position of the mouse on screen, compare it to the target object, convert that to degrees, and rotate the object around the z axis.
I was facing a similar problem to the OP, this totally solved it. Thanks!
This works perfect! Here is how I altered this to work in a 2d sprite game looking down the X/Z axis and only rotating the object on the z axis while keeping the x and y still so the sprite is facing the camera always...I could be doing something wrong but its working perfectly. ins$$anonymous$$d of the mouse I am pointing at "fireTarget"...this could easily be switched to mouse if needed.
var angle = $$anonymous$$athf.Atan2((fireTarget.transform.position.z - armCont.transform.position.z), (fireTarget.transform.position.x - armCont.transform.position.x)) * $$anonymous$$athf.Rad2Deg;
arm.transform.localEulerAngles = Vector3(0,0,angle -270);
I have been trying to get a LookAt()/RotateTowards() to work for something similar to this for hours now, to no avail. A few modifications to the code you posted and and now the rotation of my object is working perfectly! Thanks for the post Dusk!
im doing same operations in C#.....im getting an error...at Quaternion.Euler....wat am i doing wrong....???
Here's a C# version of the Update() function, simplified slightly:
var mouse = Input.mousePosition;
var screenPoint = Camera.main.WorldToScreenPoint(transform.localPosition);
var offset = new Vector2(mouse.x - screenPoint.x, mouse.y - screenPoint.y);
var angle = $$anonymous$$athf.Atan2(offset.y, offset.x) * $$anonymous$$athf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, angle);
Answer by tknz · Dec 04, 2013 at 12:22 PM
Dusk's answer workd for me. Here is a c# version that might be useful:
void Update () {
//rotation
Vector3 mousePos = Input.mousePosition;
mousePos.z = 5.23f;
Vector3 objectPos = Camera.main.WorldToScreenPoint (transform.position);
mousePos.x = mousePos.x - objectPos.x;
mousePos.y = mousePos.y - objectPos.y;
float angle = Mathf.Atan2(mousePos.y, mousePos.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0, angle));
}
For lines 7 and 8 couldn't you do
mousePos.x -= objectPos.x;
mousePos.y -= objectPos.y;
Answer by StephanK · Jan 26, 2010 at 09:09 AM
You can do something like this:
Vector3 mousePos = Input.mousePosition; mousePos.z = -(transform.position.x - Camera.mainCamera.transform.position.x);
Vector3 worldPos = Camera.mainCamera.ScreenToWorldPoint(mousePos);
transform.LookAt(worldPos);
Your guns z-axis (transform.forward) will always point in the direction of you mouse pointer on your 2D-Plane.
Explanation: A cameras ScreenToWorldPosition() will transform a point on your screen to a point in the world. As a mousePosition only has to Coordinates (it's moved on a plane...) You have to tell the ScreenToWorldPosition() method "how far into the screen it should look". Or the distance to the plane that you want to project on.
4 simple lines of code did the trick. No trigonometry involved, no planes and no raycasting. Great for what it was intended to do. Thanks, I've been looking for this!
This solution won't work for a 2D game that is on the X/Y plane (camera looking into the positive Z axis) which is Unity's default for it's new 2D features. The problem is the transform.LookAt() function won't return the desired result. For such a game, Dusk's solution (see below) will work.
i have this to work with the transform.position.x set to y. Now it follows my mouse left, right, up and down. But it is always facing up to much. How can i achieve that it is still following but it is facing to the right direction?
Its even easier now:
var point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.LookAt(new Vector3(point.x, point.y, transform.position.z));
Answer by Neo · Jan 29, 2010 at 06:20 AM
Thanks for your help, but it did not work :-( The weapon would not rotate at all. Let me post what I have.
function Update () { var mousePos : Vector3 = Input.mousePosition;
mousePos.z = (transform.position.x - Camera.mainCamera.transform.position.x);
var worldPos : Vector3 = Camera.mainCamera.ScreenToWorldPoint(mousePos);
transform.LookAt(worldPos); }
Also copied what you had into C# same thing of course. If anyone has any ideas on how to make it rotate I sure would appreciate it.
It is best practise to reply to an answer in the comments. Please move this to the correct place once you got enough points. Unfortunately new users are not given enough points to comment and we can't do much about it :-(
$$anonymous$$y apologies, that was clearly not my intentions. I just wanted to reply back to the guy, but thank you for letting me know how the system works. If I understand you correctly I must wait until I get more points to remove my answer? I tried to edit and delete but it would not let me save. Let me know what I should do and you have any ideas on the mouse rotation :-)
@Neo one thing you can do, and generally should :) is update your original post with new information, even if is in response to an Answer. (and you could also add a comment to let them know). Especially if it something like code - also, you can re-edit it to make the code look like code - highlight it, and select the "1010101" button, it turns the text into a code block. Easier to read.
I had the same problem and that partially (90%) solved it. The mechanic works but it isn't firing in a straight shot, there is a curve in the movement of my bullets when I fire them towards the mouse. The rest seems to be fine.
Answer by tadadosi · May 27, 2020 at 12:50 PM
I'm using this one in my games, it should work without issues. Apart from having the lookAt2D function, it offers a simple dropdown to choose between X and Y axis and also a bool to easily invert the direction.
Code:
using UnityEngine;
public class LookAt2D_v2 : MonoBehaviour
{
public Camera cam;
public enum Axis { x, y }
public Axis axis = Axis.y;
public bool inverted;
private Vector3 mousePosition;
private Vector3 lookAtPosition;
private void Update()
{
if (cam == null)
{
Debug.LogError(gameObject.name + " target missing!");
return;
}
// store mouse pixel coordinates
mousePosition = Input.mousePosition;
// distance in z between this object and the camera
// so it always align with the object
mousePosition.z = -cam.transform.position.z + transform.position.z;
// transform mousePosition from screen pixels to world position
lookAtPosition = cam.ScreenToWorldPoint(mousePosition);
// Calculate normalized direction
Vector2 direction = (lookAtPosition - transform.position).normalized;
Debug.DrawRay(transform.position, direction * 20f, Color.blue);
switch (axis)
{
case Axis.x:
if (!inverted)
transform.right = direction; // Point x axis towards direction
else
transform.right = -direction; // Point x axis towards inverted direction
break;
case Axis.y:
if (!inverted)
transform.up = direction; // Point y axis towards direction
else
transform.up = -direction; // Point y axis towards inverted direction
break;
default:
break;
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(lookAtPosition, 0.2f);
}
}
Your answer
