Sign in to follow this  

Unity [C#] Getting ray from mouse position

This topic is 1882 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm trying to build a small game in Unity and I ran into this problem. I want to use an unlocked cursor in the game meaning that the look at vector of the camera would not exactly point to the cursor. This is the default setting in Unity it's done by not locking the cursor the center of the screen and simply using the offset, instead the camera moves by the distance that the user moved the cursor. This allows me to use a hardware cursor in the game and also I kind of like the feel of it since the game I have in mind involves a lot of 3D picking. So the problem is that when I try to actually shoot a ray from camera through the cursor (converted to 3D position) the shooting vector is off by a lot at certain camera angles and very close to what it's supposed to be at other angles. I'm not sure what's causing it, this is the code I have so far (except from a Unity C# script)
[code]
vector3 v = Camera.ScreenPointToRay(mousePos)
ray = v.direction;
[/code]

I'm not exactly sure how to fix this or even why it's happening. I suspect that the conversion of the 2D cursor to 3D space results in a false Z value in some camera orientation but I don't exactly how to fix it. Any help appreciated

Share this post


Link to post
Share on other sites
From the documentation, ScreenPointToRay takes a screen position in pixels. Are-you sure that your mousePos is in pixels? It's not clear from your post what the 2D to 3D converstion your talking about exactly is. As far as I know, you shouldn't have any 2D to 3D conversion to do.

Share this post


Link to post
Share on other sites
[quote name='Faelenor' timestamp='1353071694' post='5001529']
From the documentation, ScreenPointToRay takes a screen position in pixels. Are-you sure that your mousePos is in pixels? It's not clear from your post what the 2D to 3D converstion your talking about exactly is. As far as I know, you shouldn't have any 2D to 3D conversion to do.
[/quote]

I meant converting a 2D cursor postion to 3D world space, at least that's what I thought I had to do. I just noticed the doc says that z coordinate is ignored, but then how does it build a ray if the z is ignored? And yes the mousepos is in pixels just checked the doc Input.mousePosition. I hope that I stated my original problem clearly. I basically want to use the actual distance that the mouse moved instead of the deltaX deltaY to control the camera view. So you could still move the cursor normally and it would feel like a normal cursor rather then crosshairs in an fps.

Share this post


Link to post
Share on other sites
Well, a ray is defined by two things: its start position and a direction. The start position is the camera position and the direction is what is returned by ScreenPointToRay. The z component of the mouse position is useless, because the direction will be the same for any point in space that appears to be at that pixel position. I don't know if I'm clear enough. Think of it as a wire starting from the camera and going away to infinity. Any point on this wire has the same pixel position but different z values. That means that we can ignore the z value to get the ray direction.

Share this post


Link to post
Share on other sites
[quote name='Faelenor' timestamp='1353090642' post='5001595']
Well, a ray is defined by two things: its start position and a direction. The start position is the camera position and the direction is what is returned by ScreenPointToRay. The z component of the mouse position is useless, because the direction will be the same for any point in space that appears to be at that pixel position. I don't know if I'm clear enough. Think of it as a wire starting from the camera and going away to infinity. Any point on this wire has the same pixel position but different z values. That means that we can ignore the z value to get the ray direction.
[/quote]

You made an example of a wire going from the camera to infinity, and I'm assuming the camera's lookAt vector 'z' is used to make the 3D ray that points in that direction but also has all the 3D points that that pixel contains because as you said it remains constant. But isn't that assuming that the camera lookAt vector is pointing at the object on which you clicked? Please correct if I'm wrong because I very well could be. But assuming that's so, in this camera model I'm trying my pointer doesn't point to the same place the character is looking at because by the time I drag the cursor from left to right of the screen, the game character would have made a few turns around the up axis. This way the cursor ends up in random places like being at the very bottom of the screen when the character is looking directly up or could be in upper left of the screen when he's facing directly forward. Assuming all of this how then can I get the actual direction point I'm clicking on? Again correct me if I said anything off, I'm just starting trying to understand raycasting and picking as I'm going through this book. Edited by VanillaSnake21

Share this post


Link to post
Share on other sites
The look at direction of the camera is the ray direction for the center of the screen only, for the other pixels, you need to call ScreenPointToRay. I'm really not sure I understand what you mean, so please try to explain what you're trying to do with more details or post some code.

By the way, your initial example is wrong, the ScreenPointToRay method returns a Ray, not a vector. Did you really use this code?

Share this post


Link to post
Share on other sites
[quote name='Faelenor' timestamp='1353350922' post='5002408']
The look at direction of the camera is the ray direction for the center of the screen only, for the other pixels, you need to call ScreenPointToRay. I'm really not sure I understand what you mean, so please try to explain what you're trying to do with more details or post some code.

By the way, your initial example is wrong, the ScreenPointToRay method returns a Ray, not a vector. Did you really use this code?
[/quote]

I've been using ScreeinPointToRay and it doesn't work. The ray that I get doesn't go from camera to the object I hit. I don't know how else to explain it. Imagine a character facing directly forward, in most games that would also mean that the cursor or crosshairs are also directly in the middle of the screen. I could have my cursor be located at ANY point on the screen while the character is still facing forward. So lets say I click the mouse button while pointing at a rock on the ground (rember the character is facing forward so the rock is at the lower right corner of the screen). How would I get a ray that goes from camera to rock?

Share this post


Link to post
Share on other sites
ScreenPointToRay does exactly that: compute a ray for any pixel position on screen. Of course this works for any position on screen and not only for a centered crosshair, otherwise the function wouldn't take any parameter! If it doesn't work, it means you're not using it correctly and that's why I asked you to post some code. Edited by Faelenor

Share this post


Link to post
Share on other sites
I guess I should have posted code earlier but I wanted to see if I could understand what's going on first, it would be pretty embarassing if I've been using this simple function in the wrong way all this time... Allright so here's the main code, it's attached to my Player character:

[source lang="csharp"]
//Activates when user presses a left mouse button
if(Input.GetButtonUp ("Fire1"))
{
Rigidbody bulletInst = Instantiate(bullet, transform.position, transform.rotation) as Rigidbody;
Ray camToCursorRay = Camera.main.ScreenPointToRay(Input.mousePosition);
shotDirection = camToCursorRay.direction; //public global float used to monitor this var
bulletInst.AddForce(shotDirection * shotPower); //shotPower multiplier set to 1500f


}[/source]

Share this post


Link to post
Share on other sites
What's transform.position? If it's not the camera position or ray origin, then the direction won't point to where you clicked. And by the way, I think it would be better to give an impulse to your bullet by setting its velocity directly instead of using AddForce.

Share this post


Link to post
Share on other sites
[quote name='Faelenor' timestamp='1353438714' post='5002727']
What's transform.position? If it's not the camera position or ray origin, then the direction won't point to where you clicked. And by the way, I think it would be better to give an impulse to your bullet by setting its velocity directly instead of using AddForce.
[/quote]

The script is attached to the Player character so it's the center of the player capsule. While it's not the camera transfrom, camera is also attached to this player and it's position is maybe 0.1 units up in y direction from player capsule, but let me try to set it to camera explicitly.

Edit: Yes that was it! The ball flies in the right direction, and I'll look into setting the impulse, thanks Faelnor! Edited by VanillaSnake21

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Similar Content

    • By loyalsheep
      Hey guys!
      Check out the trailer of Airavat. It's a minimalist, space survival game (and hard, very hard) 
      Download on GooglePlay: Airavat
       
    • By anomalystudiospt
      Hey, we are new around here!
      Our team spent the last year developing a prototype game called Rise of The Fey, a game that focuses on a dramatic story with a fast paced gameplay.
      Rise of The Fey is a third-person action-adventure RPG set within a fantasy world called Perrah. In Rise you control Kall, a young spaunian looking for revenge after the death of his beloved.

      We would appreciate if you could take a look at our stuff, tell us what you think and possibly help us out on Indiegogo.
      The prototype is in portuguese, sorry about that!
      Have a good one!
    • By juglar
      Hi guys, we are developing a game called BiteOff! based on Zombies topic. BiteOff! is based on a game strategy mechanics, free to play, where the player has a bunch of zombies and he can distribute them along the map landscape to be able to bite and transform all humans into each level. Humans are controlled by artificial intelligence and they differ each other on capabilities based on different weapons that give them three different levels of aggressiveness to defend against the zombies. The zombies are also presented in three types and they are differentiated by their attack, speed, strength and resistance abilities. Through different achievements, (time to eat all humans, score, among others) the player can access four extra skills that can enhance your attack in real time on next levels as power-ups.
      We are launching a crowdfunding campaign in kickico and we need some helps please visit us on the crowdfunding page https://www.kickico.com/es/campaigns/17824/biteoff-the-videogame 
      Twitter @biteoffthegame
      Facebook
      Clickme!
      Website 
      Clickme!
    • By Lord McMutton
      The world of Ethios is held aloft by massive trees known as the Pillars.
  • Popular Now