- Home /
Top down aim at mouse
So I have this top down 3D shooter when the player aim at the mouse position but just doesnt seem very accurate, the player just never seem to truly aim towards the mouse as it is always looking at an offset, anyone knows why? :)
var objectPos = Camera.main.WorldToScreenPoint(transform.position);
var dir = Input.mousePosition - objectPos;
transform.rotation = Quaternion.Euler (Vector3(0,Mathf.Atan2 (dir.x,dir.y) * Mathf.Rad2Deg,0));
Answer by maccabbe · Mar 25, 2015 at 03:01 AM
The reason this is not working is inaccurate is because you are getting the rotation in terms of screen space instead of world space. Notice that the the rotation is less accurate the more you rotate your camera along the x axis.
To get the target in terms of world space first make a ray from the mouse using
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
You will want a plane to intersect with the ray, in this case I'll use the ground.
Plane plane=new Plane(Vector3.up, Vector3.zero);
Then get the target using intersect the plane and ray using a plane raycast
float distance;
if(plane.Raycast(ray, out distance)){
Vector3 target = ray.GetPoint(distance);
}
Then you can use the x and z components of the direction vector with Mathf.Atan2 like you did in your code. So your overall code will be like
Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition);
Plane plane=new Plane(Vector3.up, Vector3.zero);
float distance;
if(plane.Raycast(ray, out distance)) {
Vector3 target=ray.GetPoint(distance);
Vector3 direction=target-transform.position;
float rotation=Mathf.Atan2(direction.x, direction.z)*Mathf.Rad2Deg;
transform.rotation=Quaternion.Euler(0, rotation, 0);
}
in the raycast, whats the "out variableName" correspond to in javascript, kinda should have mentioned that..
otherwise i have now this code; for some reason the angle is off by 90degree and still get the same problem??
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var plane : Plane = new Plane(Vector3.up, Vector3.zero);
var distance : float;
if(plane.Raycast(ray, distance))
{
var target : Vector3 = ray.GetPoint(distance);
var direction : Vector3 = target-transform.position;
var rotation : float = $$anonymous$$athf.Atan2(direction.z, direction.x) * $$anonymous$$athf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, -rotation, 0);
}
In javascript you can just ignore the out keyword, your code is correct.
I fixed the angle calculation (line 7) to fix the angle being off by 90 degrees.
Right now the plane is on the ground so your guy will look at the point your mouse intersects with the floor. It might be better to set the plane to match eye level, you'll have to make a design choice. Use the following (replace 0.5f with whatever you want eye level to be)
Plane plane=new Plane(Vector3.up, new Vector3(0, 0.5f, 0));
i think at the last line it should just be "rotation" and not "-rotation" right? otherwise seems to work like wat i had when i started which is fine... T_T cause turns out its not an ai$$anonymous$$g problem, issue was that i was using a custom cursor, like a crosshair and u need to set the cursor hotspot in the player settings to be in the center so yea... sry and thanks :)
[Edit], actually you're code seem better with games that has height and isnt viewed directly from the top, so was definitely helpful in the end :)
Answer by davient · Mar 25, 2015 at 02:56 AM
Hi there, what you need is Transform.LookAt(). And, to convert coordinates space using ScreenToWorldPoint. The below code should do ya :)
using UnityEngine;
using System.Collections;
public class LookAtMouseScript: MonoBehaviour {
public Camera cam;
private GameObject gob; // we will place this object at the mouse position
void Start () {
gob =new GameObject();
}
void Update () {
// position target object at mouse point
gob.transform.position = cam.ScreenToWorldPoint(Input.mousePosition);
// point our object at the dummy object
transform.LookAt(gob.transform, Vector3.forward);
}
}
Answer by BarthaSzabolcs · May 04, 2021 at 01:27 PM
I know it's an old post, but this is still a valid problem.
I made a 3 minute tutorial about this with explanation and an example project.
My Solution
using UnityEngine;
namespace BarthaSzabolcs.IsometricAiming
{
public class IsometricAiming : MonoBehaviour
{
#region Datamembers
#region Editor Settings
[SerializeField] private LayerMask groundMask;
#endregion
#region Private Fields
private Camera mainCamera;
#endregion
#endregion
#region Methods
#region Unity Callbacks
private void Start()
{
// Cache the camera, Camera.main is an expensive operation.
mainCamera = Camera.main;
}
private void Update()
{
Aim();
}
#endregion
private void Aim()
{
var (success, position) = GetMousePosition();
if (success)
{
// Calculate the direction
var direction = position - transform.position;
// You might want to delete this line.
// Ignore the height difference.
direction.y = 0;
// Make the transform look in the direction.
transform.forward = direction;
}
}
private (bool success, Vector3 position) GetMousePosition()
{
var ray = mainCamera.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hitInfo, Mathf.Infinity, groundMask))
{
// The Raycast hit something, return with the position.
return (success: true, position: hitInfo.point);
}
else
{
// The Raycast did not hit anything.
return (success: false, position: Vector3.zero);
}
}
#endregion
}
}
Your answer
Follow this Question
Related Questions
Mouse aims at object ? 1 Answer
Make my Gunpoint aim/rotate on the z axis towards my mouse cursor 1 Answer
Cast a cursor into world space from a game object? 0 Answers
How in the world do I ACCURATELY place an object at the mouse? 3 Answers
While holding down the mouse button make object rotate to mouse cursor 1 Answer