https://vimeo.com/727183201
I’ve been trying to cast a ray in front of my controller in my vr game (using the oculus SDK) in order to press buttons. Currently, I’m using a ray going from my controller’s position forwards using transform.forward. This works fine at one unit length (I’m using a line renderer to try to trace the ray). However, when I go any longer than 1 unit, the ray goes off in an unpredictable direction. I was able to find what path it’s following and the intended path using the aforementioned line renderer:
As you can see, it’s a matter of the position of the parentheses, but I can’t figure out how to raycast using the correct line.
Thank you!
Edit: I added a video. My goal is to point the controller at the 2d plane to play the 360 video. The red line is the raycast, it behaves strangely as you can see, and I could start the video even if my controller were facing me. The white line is the goal, where I want the raycast to be.
Keep in mind that controllers in VR always fluctuate even when you put them on a table their transform.forward may jitter slightly. This is similar to, if not identical, mobile phones and their gyroscope.
You can smooth out the motion by sampling multiple frames, though this introduces delay. Or high-pass filtering like for mobile phone gyroscopes.
What is the red line in the video?
Have you considered that transform.forward may not be the direction the controller points to? Refer to headset SDK documentation or examples for more information on how to handle pointing with the controller.
In your code above you are also mixing transform.position and controller.transform.position, so the raycast doesn‘t seem to be using the controller‘s transform.
I’ve read through the documentation for raycasts, transform.forward, etc. thoroughly and it hasn’t helped. As far as I can tell, direction is just the point it travels towards to generate the ray, which is exactly what I’m trying to use it for. Also, a ray from transform.position to transform.position + transform.forward is the correct ray that I was hoping to use, which I’ve seen based on setting the line renderer to just those two points. I’ve tested it thoroughly, and the raycast works as expected until I scale it past one, so it shouldn’t be an issue with the ray/direction.
As I mentioned in the edited initial message, the red line is the functional line that behaves strangely, it represents the raycast. I’ve tested it, and trasform.forward does represent the direction the controller points to. I’ve checked the Oculus documentation, and didn’t see any mention of controller pointing (although they probably should, thanks for the suggestion!). The reason I use controller.transform.position in some lines is because they are actually in two different files, which shouldn’t make a difference to raycast behavior since they are unrelated other than that I put the same functions into both.
transform.position + transform.forward is a vector describing point not a direction. Raycast method expects a point and a direction as arguments not two points. If you don’t understand difference between a point and a direction you need to read some articles about use of vectors in game development and describing 3d space. Or take a pieces of graphing paper, draw some vectors and manually do some calculations for corresponding coordinates to better understand the math behind it. of In this specific case you should probably pass transform.forwad as second argument to raycast method.
Thank you so much, I understand now! That fixed the issue! I didn’t realize the direction was based on a direction from the origin rather than from the initial point.
I’m glad you solved your issue, but I think there might be more to this problem than just mixing up the fundamental idea between points and directions. I added a child fingertip gameobject at the tip my VR finger and created a ray pointing outward following the index finger. I defined my origin as fingertip gameobject (transform.position) and the direction as (transform.position + transform.forward). I setup the raycast as normal for using a ray i.e. Physics.Raycast(ray, out RaycastHit hit, 5.0f). I was getting collider hits far away from where I was pointing. When I multiplied by 5 (transform.position + transform.forward5), I was getting collider hits that were closer but still inaccurate. When I multiplied by 100 (transform.position + transform.forward100) my collider hits were where I expected. This surprised me because I didn’t think that extending the ray should have changed the angle of the ray. Just to check, I added a quick lineRenderer based on the ray.origin and ray.getpoint for when the ray was defined shorter vs medium vs long and indeed the angle was different. Not sure why this is the case, but for now I’m making all my rays long even if my raycast is short.
@The11thAlchemist Please don’t. You are repeating the same mistake original poster did. Did you even try the suggested fix of passing just “transform.forward” instead of (transform.position + transform.forward) or (transform.position + 100 * transform.forward)?
The reason why multiplying forward by some constant seems to makes things better because as the constant gets bigger the contribution of transform.position to the final result get’s smaller. Instead of multiplying forward by some big constant (transform.position + 5 * transform.forward) you could multiply position by a very small constant and achieve the same results (0.2 * transform.position + 1 * transform.forward). If 100 is better than 5, why not 1000 or even 1000000? So you end up with (transform.position + 1000000 * transform.forward) and (0.000001 * transform.position + 1 * transform.forward). And if (0.000001 * transform.position + transform.forward) is better than (0.2 * transform.position + 1 * transform.forward) why not (0.00000000 * transform.position + transform.forward)? 0 * transform.position + transform.forward == transform.forward
Here is an illustration:
Note that (101, 105) is almost the same as (100, 100) so it points close to the 45 degree angle original (1, 1) vector has, 46.11 to be more precise. It is much closer than 71 degrees you get from (2, 6). But the proper fix isn’t to multiply one of the subexpression by constant so big it overshadows the others, but instead to just not include the parts which shouldn’t be there.