0
\$\begingroup\$

How is it possible to get a cursors X and Y Location relative to the scene planes rather than using co-ordinates based upon pixels of screen height and width?

I have the start of a very basic game, picture with a few physical aids shown below.

I want to find out how far away the cursor is on the X and Y axis from an object in the scene. The Z axis is irrelevant due to the nature and orientation of the game, so z = 0. (Note that in Unity, the Y axis is vertical)

Basically, the distance of the cursor from the cube on the X Axis upon clicking will define the power of an action.

Because of this. I want to get the cursor X position relative to the 0 point of the scene ( or the object ), not relative to the bottom left corner of the screen.

I could then use Vector3.Magnitude() to get the distance.

How is this possible?

Image showing scene and visual aids

\$\endgroup\$
0

2 Answers 2

1
\$\begingroup\$

Since you're aiming at a known constant plane, you can do this without physics raycasting.

Vector3 GetCursorPositionOnScenePlane(float zValue = 0f)
{
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

    float depth = zValue - ray.origin.z;
    float zDirection = ray.direction.z;

    if(Mathf.Approximately(zDirection, 0f) // Ray parallel to XY plane.
       || depth * zDirection < 0f)         // Ray looking away from plane.
    {
        // Error - this ray can't see the plane!
        // This won't happen if your camera is looking at the scene plane.
        return new Vector3(float.NaN, float.NaN, float.NaN);
    }

    // Calculate how many times we need to travel along the direction vector
    // from the ray's origin before hitting our desired zValue:
    float scale = depth/zDirection;

    return ray.origin + scale * ray.direction;
}

Note that this differs from Camera.ScreenToWorldPoint in that the zValue here is a z position in world space, so your outputs are always in a world-XY-aligned plane. ScreenToWorldPoint's z is a distance from the camera, so if the camera is rotated then the plane of its outputs may be tilted relative to the world XY plane.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks DM, I'll have to try this - it's a lot cleaner and makes more sense to me than the other script. \$\endgroup\$
    – Panomosh
    Commented Feb 25, 2016 at 13:25
  • 1
    \$\begingroup\$ @Panomosh I've made a quick edit so the script works for arbitrary z values. \$\endgroup\$
    – DMGregory
    Commented Feb 25, 2016 at 13:50
1
\$\begingroup\$

It is possible and Unity documentation is very helpful in this matter. First you need a ray to raycast from mouse position, the documentation for mouse position provides an example how to get a ray from mouse position:

public class ExampleClass : MonoBehaviour {
    void Update() {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    }
}

because you are not interested in all of the objects(just the plane*), following to documentation of Physics.Raycast will tell you all possible overloads, one of them having a layer mask. You are also interested in position, so choosing an overlaod with RaycastHit and following documentation to RaycastHit tells you there is a ".position":

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void Update() {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        int maskOfPlane = 1 << planeLayer;
        if (Physics.Raycast(ray, out hit, maskOfPlane)) {
            //one of coordiantes being always zero for aligned plane
            var position = hit.position;//this is relative to 0,0,0
            var relativePosition = other.transform.position - position; //relative to a gameObject other
        }
    }
}

*literally place an invisible plane in the world aligned with your games logical plane and move it to a custom layer, you will need to set the mask against it.

\$\endgroup\$
1
  • \$\begingroup\$ This is perfect, thank you wondra. I Appreciate the effort. \$\endgroup\$
    – Panomosh
    Commented Feb 25, 2016 at 12:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .