Answers for "Code behind 'Camera.ViewportPointToRay'?"
http://answers.unity.com/questions/1695275/code-behind-cameraviewportpointtoray.html
The latest answers for the question "Code behind 'Camera.ViewportPointToRay'?"Answer by Bunny83
http://answers.unity.com/answers/1695591/view.html
I've just tested this one and it works quite well. The numerical error compared to Unity's own ViewportPointToRay method is at the 5th decimal place. Drawing the rays 100 world units into the scene you can barely see the error. Unity might use some different internal order. However the results are pretty spot on.
public static Ray ViewportPointToRay(Vector2 aP, Matrix4x4 aProj, Matrix4x4 aCam)
{
var m = aProj * aCam;
var mInv = m.inverse;
// near clipping plane point
Vector4 p = new Vector4(aP.x*2-1, aP.y*2-1, -1, 1f);
var p0 = mInv * p;
p0 /= p0.w;
// far clipping plane point
p.z = 1;
var p1 = mInv * p;
p1 /= p1.w;
return new Ray(p0, (p1-p0).normalized);
}
Note that aProj need to be the camera's projection matrix and aCam need to be the camera's worldToCameraMatrix. Also note that worldToCameraMatrix is just the camera's worldToLocal matrix but with the z axis inverted like this:
var w2c = Matrix4x4.Scale(new Vector3(1, 1, -1)) * cam.transform.worldToLocalMatrix;
<br>
I've tested this method with a perspective and an orthographic camera and it works like expected.Fri, 31 Jan 2020 13:44:12 GMTBunny83Answer by Namey5
http://answers.unity.com/answers/1695491/view.html
ViewportToRay would work very similar to ViewportToWorld, but with the added step of finding the direction of said point from the camera;
Ray ViewportPointToRay (Vector3 pos, Camera cam)
{
//Remap to NDC-space [-1,1]
pos = pos * 2.0f - Vector3.one;
pos.z = 1f;
//Find the world-space position of the point at the camera's far plane
Vector3 worldPos = cam.cameraToWorldMatrix.MultiplyPoint (cam.projectionMatrix.inverse.MultiplyPoint (pos));
//The ray's origin is just the camera's position. Alternatively, you could use the same
//matrix logic above and find the same point at the camera's near plane and use that instead
Vector3 origin = cam.transform.position;
return new Ray (origin, worldPos - origin);
}
The Unity documentation for the internal function makes a very interesting point; the z-position is ignored. In this case, because distance is irrelevant in relation to a ray, we just assume the viewport point lies on the camera's far plane.Fri, 31 Jan 2020 06:18:53 GMTNamey5