ScreenToWorldPoint creating RayCast/DrawRay offsets?

Hi all.

I am prototyping a third person aiming system that uses ScreenToWorldPoint vectors. The way it works is the cursor used by the player has a degree of freedom to move around the screen before moving the camera. The mouse, for example, feeds X/Y coordinates into two ScreenToWorldPoint vectors, these two vectors share those coordinates in order to align to one another. The first vector (named ‘pos’ in the code) depth sits slightly in front of the player character the second’s depth (named ‘pos2’) sits further away. The first vector (pos) sends out a RayCast from it’s position to the second vector (pos2). The second vector is in essence a reference point for the RayCast from the ‘pos’ vector. The RayCast checks for anything in between these two vectors and anything it hits it updates the position of a vector (not yet implemented here) that the player character actually shoots projectiles at when firing. It also updates he position of a cursor object in 3D space to give a better sense of depth. Think Kid Icarus Uprising style of shooter.

The reason I’m using this method instead of ScreenPointToRay is because a RayCast from that would detect anything that’s directly behind the player character (even the player itself) creating undesired behavior. I know I could mess around with layers but this is just a test.

The problem I have is this: I have the two vectors ‘pos’ and ‘pos2’, values ‘x’ and ‘y’ to move them around the screen and I also have two GameObjects called ‘hori’ and ‘verti’. hori is a horizontally scaled plane and verti is vertically scaled plane. These game objects are simply visual aids to ensure the vectors are aligning as intended. hori updates it’s position to pos vector and verti to pos2. These work fine: hori and verti align perfectly when shifting the x/y values while running the game. They work as intended perfectly. So then I run a Debug.DrawRay as a stand in for a RayCast between ‘pos’ and ‘pos2’ and that’s when things fall apart: the DrawRay (colored green) starts from ‘pos’ but has a drastic vertical offset from it’s intended ‘pos2’ target and when moving them around with the x and y values the offsets become worse with a horizontal offset becoming apparent. I run other DrayRay tests, a ScreenPointToRay (colored yellow) pointing to ‘pos’ that hits it’s target okay but a DrawRay (colored blue) from the camera’s position to ‘pos’ also has an offset missing it’s target completely. I don understand what’s wrong here because the GameObjects hori and verti are in the position they should be in but the vectors aren’t translating the same way for the DrawRays/RayCasts. Am I missing something or have misread something here? It makes no sense to me. If worst comes to worst I could use two empty objects to sit in the vector positions and ray cast from one to the other with those but I don’t understand why it doesn’t work as it should.

Thank you.

public class RayTest : MonoBehaviour
{
    public int x;
    public int y;
    public float range1 = 3;
    public float range2 = 6;
    Camera cam;
    Vector3 pos;
    Vector3 pos2;
    Vector3 camPos;

    public GameObject hori;
    public GameObject verti;

    private void Start()
    {
        cam = GetComponent<Camera>();
    }

    private void Update()
    {
        pos = cam.ScreenToWorldPoint(new Vector3(Screen.width/ 2 + x, Screen.height / 2 + y, range1));
        pos2 = cam.ScreenToWorldPoint(new Vector3(Screen.width / 2 + x, Screen.height / 2 + y, range2));
        camPos = new Vector3(Screen.width / 2 + x, Screen.height / 2 + y, range1);
        Ray ray = cam.ScreenPointToRay(camPos);


        hori.transform.position = pos;
        verti.transform.position = pos2;

        //debug ray the camPos ScreenPointToRay
        Debug.DrawRay(ray.origin, ray.direction * range1, Color.yellow);

        //debug ray the ScreenToWorldPoint vector pos to ScreenToWorldPoint vector pos2 
        Debug.DrawRay(pos, pos2, Color.green);

        //debug ray the camera's postion to the ScreenToWorldPoint vector pos 
        Debug.DrawRay(this.transform.position, pos, Color.blue);


    }
}

DrawRay expects a worldspace position as the start position and a worldspace direction vector. However you pass it a worldspace position instead for your green line. If you have two worldspace positions you probably want to use Debug.DrawLine instead. It expects the two endpoints.

Your yellow line is correct because you pass ray.direction * range1 as direction. So it’s a relative direction vector and not a position.