full 360 Aiming at the mouse pionter in 2d (SOLVED)

Ok I have no idea how to describe it in the subject pane but heres what i want to do.

I want to aim an object at the mouse pionter in a 2d sidescroller no mater where the mouse is and this object moves around the screen with the player.
I have tried this:

function Update() 
{ 
   transform.eulerAngles.y = 180 * ((Input.mousePosition.x - Screen.width / 2) / (Screen.width / 2)); 
}

but i get funny rotations and it only works as if i’m looking down on it. these rotations are about 180 then they go backwards if the mouse is below the player
i tried changing 180 to 360 but that gives pretty much the same effect only the rotation speed doubles.
so it no longer looks at the pointer. anybody know how this is done?

kinda like this http://www.youtube.com/watch?v=n_ATFQXhMaM

Short answer: atan2(). Pseudocode:

float dx = mouse_x - screen_center_x;
float dy = mouse_y - screen_center_y;
float angle = atan2(dy, dx);
transform.eulerAngles = Vector3(0, angle, 0);

Note that you’ll need to add any necessary degrees<->radians conversions, and you may also need to tweak the code to account for the player object lying in the xz plane.

Actually, here’s a better answer. Look for the ‘Evac City’ tutorial, as it includes code for doing exactly what you’re describing.

[Edit: If your player is not always at the center of the screen, you’ll have to adjust the code so that the angle is computed relative to the player position rather than the center of the screen, and so that the mouse position and player position are expressed in the same space.]

any links i have tried for evac city gives me the error 404 message believe me i’ve fully seached this to the best of my ability it surprises me how this is such an uncommon question

Here you go.

Thank you very much for the help but i’ll be honest here.
I am Fucking Lost, I mean Amazonian Jungle lost. I am used to JS yes, (though i’m still learning) but “Fuck”… this means nearly nothing to me. and the act that integrating this into the already semi-compiled player controll script i have here it means either scrap that and use c# which won’t happen, or Pick out the bits specific to my purposes and convert the method over to JS which i have no idea how to do at all. so is there by some wild strech of the imagination that this has been converted to a more JS esque format? (Didn’t think so)
I will say this I have established for the greater part what components of this script serve my purposes, from reading through the tutorial part on this, but implementing this in js Is lost on me completely.

anybody got a JS solution?

Edit: May I note i have yet to find a confirmed success with this in JS is this like the holy grail or sumut?

Does the player in your game stay at the center of the screen, with the environment scrolling around it? Or does the player itself move around the screen?

the player moves around the environment (sidescroller) and the camera follows with a slight delay and catches up once the player stops moving, this camera type has been established and is working.

The exact behavior i want is for the weapon object to look directly at the mouse cursor on the screen

If you haven’t gotten this problem solved yet, here’s what I’d recommend trying.

The first thing you’ll need is a world-space position corresponding to the current mouse position, and lying in the plane in which the game takes place (it looks to me as if this is the xz plane).

For this step, there are a few Camera class functions that you could probably use (e.g. ScreenToWorldPoint()). What I would probably try first is ScreenPointToRay(), which will return a ray originating at the camera position and passing through the mouse screen position. You can then intersect this ray with the xz plane to yield the corresponding world position.

(I’d recommend breaking this problem into separate parts to make it a bit easier to solve. The first thing I’d do is create a temporary ‘debug’ entity with a visual attached to it, and match its position to the world-space position computed in the previous step. If all works well, it should follow the actual mouse position very closely, and you can then move onto the next step.)

All that remains is to compute the angle for the rotating object attached to your player based on its position and the mouse’s world-space position. As described earlier, this can be done using atan2(). Now that we’re computing the angle with respect to the xz plane, the pseudocode might look something like this:

Vector3 diff = mouseWorldPosition - transform.position;
float angle = Mathf.Atan2(diff.z, diff.x);
transform.eulerAngles = new Vector3(0, angle, 0);

Don’t forget to add any necessary degrees<->radians conversions. Note also that this assumes the object points along the +x axis in local space.

If you try this and the object rotates in response to mouse and player movement, but rotates the wrong way and/or points in the wrong direction, you may need to tweak the arguments to and/or the return value of Atan2() accordingly.

It might seem a little complicated, but there are really only a couple of steps involved, which you can tackle one at a time. If you have trouble implementing any of this, you can always post back here with questions.

Thank you this is a much clearer description of the method I will follow these steps and post my results good or bad.

Once i get this working i’m going to make this available to the comunity,

Ok so far is good I have a visual of where the mouse is on the screen by drawing a ray to the Input Mouse Possition like so.

function Update () {
var ray = camera.ScreenPointToRay (Input.mousePosition);
Debug.DrawRay (ray.origin, ray.direction * 10, Color.red);
}

now i’m trying to figure out how to get the debug object to follow the ray. for example the player is locked to z axis (Worldspace) so the object needs to track (Intersect) the rays possition but stay on the z plane but again my attempts have lead strange behavior of the dummy object so ya i’m lost again. i’m sorry to be a hastle.

Ok so i have the dummy object following the cursor sort of
It moves in an arc around the camera and while it does follow the mouse movements by half (aprox) it also is slightly off centre being slightly over the ray(cursor) when the ray is dead centre. i have gotten this far

public var object : Transform; //Dummy object goes here
function Update () {
var ray = camera.ScreenPointToRay (Input.mousePosition);//Cast a ray from the camera through the mouse cursor
Debug.DrawRay (ray.origin, ray.direction * 20, Color.red);// draws a red line along the ray 20 units from the camera
var target = ray.direction * 10;
object.transform.position = target;// attempts to place the dummy debug object on the ray
}

so any ideas what i did wrong here?

Looks like you’re getting closer, but you’ll want to place the ‘dummy’ object in the plane in which the game takes place, not just 10 units along the ray.

What plane does the game take place in? XY? XZ? (There are some hints in your earlier posts, but I’ll go ahead and ask just to be sure.)

XY plane. X == side to side and Y == up down.

I may note the last piece of code i posted didnt actualy follow a point 10 units along the ray but more like 22-25
units along the ray and slightly above when the ray was centred

This line:

var target = ray.direction * 10;

Should be:

var target = ray.origin + ray.direction * 10;

Or, alternatively:

var target = ray.GetPoint(10);

As your code is now, the result will only be correct when the camera is at the origin.

So I would try that first, and see if the results are better. Then, try changing your ‘compute target point’ code to this:

var t = -ray.origin.z / ray.direction.z;
var target = ray.origin + t * ray.direction;

Or, alternatively:

var target = ray.GetPoint(-ray.origin.z / ray.direction.z);

This should give you the point where the ray intersects the XY plane, and this, in turn, will be the point that you’ll want to aim your object at.

Ok cool it works and using LookAt on a cube confirms that it works perfectly apart from the rotation of the cube but that is just a detail i’ll sort out next, this is just debugging to see if i can track the mouse thank you jesse.

the working code for placing a single object on the mouse at the 0 position of the Z plane is

public var object : Transform; //Dummy object goes here
function LateUpdate () {
var ray = camera.ScreenPointToRay (Input.mousePosition);
Debug.DrawRay (ray.origin, ray.direction * 20, Color.red); // (Debug.DrawRay)this is for visual confirmation and can be commented out for build.
var target = ray.GetPoint(-ray.origin.z / ray.direction.z); 
object.transform.position = target;
}

hope this helps others :smile:

ENJOY!

ok the next step has me a little stumped
I have the script set up for a dynamic crosshair that reacts as desired and stays where the mouse cursor is on the screen as well as animating the crosshair when over an enemy but the big problem is the final part before I can put this down. getting the weapon to rotate on a single plane Y in global, X in local (my prefs are with global) and look at the the crosshairs.

I have tried the Atan2 method as described above but i get small jerking motions that stop at 5 degrees or so no matter what i try that only seem to indicate an attempt to look in the direction of the cursor based on the cursors position.x but not at the cursors position.y (if that makes sense)

other attemps use variations of the LookAt methos but causes the weapon (An alphablended Texture on a plane) to flip over so yes this gives the desired result of the weapon always being the right way up i have another method to handle this effect(Flipping the image at certain rotation angles). and it doesn’t look good in a 2d platformer when the flat images start rotating in an obviously 3 Dimentional manner.

so now that i’ve rambled on is there a look at method that allows you to freeze the rotation of a certain axis or can somebody help me with the atan2 method?

If you haven’t already, I’d recommend trying Quaternion.LookRotation(). Use the vector from the player to the crosshair for the ‘forward’ vector, and use the vector perpendicular to the plane in which the game takes place for the ‘up’ vector.

I don’t know exactly how your character control works, so I can’t comment directly on the image flipping problem, but you should be able to get whatever information you need for that purpose by examining the forward vector of the rotating object after it’s been ‘aimed at’ the crosshair.

I’m not sure you understand. (or i missunderstood you)
I have managed to get the players weapon to look at the target and from what i can tell the Quaternion.LookRotation doesnt seem that much different to the LookAt method. (unless i’m missing something) I may just clamp the angles near 91 and 269 and just swap the plane out for another one clamped at 89 and 271 and see what i get though i think that will have bugs too with the <89 but !<271 of the second clamp I dunno lemme think.

Hmmmmmmmmmmmm…

i think Mathf.Atan2 and euler angles needs to be re’visited I honestly think I did it wrong the first time.

I thing i need to be clear on this bit though cos i get the feeling i’m not being entirely understood
the top and bottom of the cube object i’m using to test the rotation when the mouse is on the left hand side of the player is the same as the top and bottom of the cube object when the mouse is on the right hand side of the player.

ie: at angles 90 and 270 the cube just flips over on its local y so that the top is always the top.

I would love to know why something can be rotated around in a circle on a horizontal plane but as soon as you try and rotate around on a vertical plane the object wants to do jymnastics.

Edit: do you think that maybe using trasform.Rotation to set the rotation of the local y dependant on the cursors x position relative to the players x position might work?

Can you post the code that you’re using to orient the object towards the cursor?

Hah ha i just figured it out :twisted:

i used this and it works perfectly lol

var target : Transform;
function Update ()
{
	transform.LookAt(Vector3(target.position.x, target.position.y, transform.position.z)); 
}

so F@*king simple

Edit: thank you so much for the help and support Jesse your a star 8)

CASE CLOSED!