mouse over hit position under other objects.

Hello. I am using a Mouse Over Any sensor to find the hitPosition between my mouse and a plane. Somtimes during my game objects get in between my mouse and the plane. How do I get the hit position of the mouse on the plane when there are objects in between the mouse and the plane as if there were no objects in between the mouse and the plane. Thank you.

  1. You can get the screen position of the mouse directly rather than getting it’s hitposition (eg if the plane is a menu system)
  2. You can ‘jump’ the ray, so if it hasn’t hit the object you want it to, cast another ray starting at the hitposition of the first along the same angle. (You’ll also need to get the ray’s vector, but you can get that with some function. I can’t remember it’s name I’m afraid)

Hello. Thanks for the suggestion. Is it possible to provide a python code example of how to ‘jum’ the ray? thanks.

Goran did a good video tutorial awhile ago on this exact issue. He shows all the code you need in the video.

Thanks. This was helpful. in the video he talked about using a raycast with the mouse cursor and plane mesh with a game property. Do you know how to use this method?

Thanks.

You would manually cast a ray from the camera to the Mouse Over sensor’s target and make it only detect an object with the property you’re looking for.

import bge

MAX_DIST = 100
TARGET_PROP = 'myProperty'

# get the mouse sensor
cont = bge.logic.getCurrentController()
obj = cont.owner
mouseSens = cont.sensors['MouseOverSensorName']

# get the start and target points of the ray
start = mouseSens.raySource
target = mouseSens.rayTarget

# cast a ray looking for the given property
hitObj, hitPoint, normal = obj.rayCast(target, start, MAX_DIST, TARGET_PROP)

I took this straight from my code. It shoots a ray directly in front of the camera up to its far clipping value. It ignores invisible objects and keeps shooting rays until the max distance. This could possibly be excessive if there are many invisible objects lined up, which in that case you could could use a for loop instead of a while loop to limit the number of iterations.

def acquire_hitobj(curSce): 
 
    actCam = curSce.active_camera 
    actCam['prevHoverTarget'] = actCam['rayCastResults'][0] 
 
    #shoot ray center screen forward direction of camera (+Y) 
    #use near/far since we can't literally see objects outside that 
    vectAxis = actCam.getAxisVect((0, 0, -1)) 
    origin = actCam.worldPosition + (vectAxis * actCam.near) 
    dest = origin + (vectAxis * actCam.far) 
 
    hitPoint = origin 
     
    # Ignore invisible targets... 
    # Could use while loop but might lag if many invisible objects in a row: 
    # while hitObj and not hitObj.visible: 
    # 4 should be a defined setting somewhere 
    for i in range(4): 
 
        hitObj, hitPoint, hitNorm = actCam.rayCast(dest, hitPoint) 
 
        if hitObj: 
            # check visibility, could check other things 
            # if visible, break 
            # else shoot another ray 
            if hitObj.visible: 
                break 
        else: 
            # nothing so break 
            break 
 
    actCam['rayCastResults'] = (hitObj, hitPoint, hitNorm)

Adapt it as needed. For example, instead of checking for visibility, you could check for a game property, etc. If you need to shoot a ray in another direction other than forward, change the vector passed to getAxisVect().

The result of this is similar to what I had when I was using the mouse over any sensor. when an object gets in between the mouse and the plane there is no hit point. I would like to obtain the hit point on the plane through objects between the mouse and it. Thanks.

Sorry, I forgot you also have to enable the xray option:

hitObj, hitPoint, normal = obj.rayCast(target, start, MAX_DIST, TARGET_PROP, 0, 1)

You can refer to the API here.

Hi Mobious. No worries. It works now. Thanks.