Make ray follow mouse position from player origin (Isometric)

I’m trying to get a firing mechanic working in my isometric game. I want to be able to shoot along the x/z-axis but not have the ray go up or down the y-axis. Instead I want it “zero’d” out on the y-axis at all times.

Also the ray doesn’t point precisely to the mouse position unless it is directly infront. As I veer left or right of the origin it keeps getting significantly less accurate at point at the mouse to the point it will be nearly 10 degrees off.

The white square denotes where the mouse cursor was. The print screen would not capture the mouse cursor for some reason.

alt text

alt text

alt text

    using UnityEngine;
    using System.Collections;
     
    public class Weapon : MonoBehaviour {
     
        public float fireRate = 0;
        public float damage = 10;
        public LayerMask notToHit;
     
        float timeToFire = 0;
        Transform firePoint;
     
        void Awake () {
            firePoint = transform.FindChild ("FirePoint");
            if (firePoint == null) {
                Debug.LogError ("firePoint is null");    
            }
        }
    
        void Update () {
     
            Vector3 mousePostion = Camera.main.ScreenToWorldPoint (Input.mousePosition);
            mousePostion.y = 0;
            Vector3 firePointPosition = new Vector3 (firePoint.position.x, firePoint.position.y, firePoint.position.z);
       
            float distToMouse = Vector3.Distance(mousePostion, firePointPosition) ;
       
            RaycastHit hit;
            Ray myRay = new Ray (firePointPosition, mousePostion);
     
            Debug.DrawRay (firePointPosition, mousePostion);
     
            if (fireRate == 0) {
                if (Input.GetButtonDown("Fire1") && Physics.Raycast(myRay, out hit, distToMouse, notToHit)) {
                    Shoot();
                }
            }
       }
     
       void Shoot () {
            Debug.Log ("Fire!");
       }
}

How do I make a ray that stays on the same Y-axis as the player, can follow the mouse’s movement along the x/z-axis in the world with precision?

When a camera is at an angle to a surface, you cannot use ScreenToWorldPoint() to find that position. The solution is a Raycast(). You could Raycast() against the green block, but if the surface is flat, then there is a cheaper way. You can use Unity’s mathematical Plane class. How to setup the code will depend on how you setup your object. In particular whether the green block surface is on the XZ plane or the XY plane. Let me assume the XZ plane. To find the position it is best to use the position of the player (or whatever object you are going to place). A bit of untested example code:

 Plane plane = new Plane(Vector3.up, player.position);
 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 float dist;
 plane.Raycast(ray, out dist);
 Vector3 pos = ray.GetPoint(dist);

So pos is where you would move an object in world space so that it would be under the mouse position. Note this code assumes that the Raycast() cannot fail. If you allow the camera to look parallel to the green block or away from the green block, then you need to check the return value of the plane.Raycast() call.

Another solution is to use Collider.Raycast() to cast against the block (or against an invisible plane that passes through the player’s pivot point).