1
$\begingroup$

Still following the same tutorial as I was following so long ago :P

At about 9:30 he mentions using rayCast() to get the intersection of the ray and any objects with a specific property.

This sounds like what I want to do, which is get the location of the point underneath the cursor on only a specific object.

Here is my script:

from bge import logic

def main():

    scene = logic.getCurrentScene()
    cont = logic.getCurrentController()
    mouse_over = cont.sensors["mouse_over"]

    if mouse_over.positive:
        tracker = scene.objects["mainTarget"]
        crosshair = scene.objects["Cross_hair"]
        floor = scene.objects["Floor"]
#        tracker.worldPosition = mouse_over.hitPosition
        tracker.worldPosition = crosshair.rayCast(floor, "isTrackerFloor", 0, 1, 0).hit

I think it should be working, except I keep getting type errors from the rayCast function arguments. I've tried shuffling them all around, but had no luck (with the above arrangement it throws TypeError: must be str, not int, which I assume means I have the property name in the wrong place?).

What is wrong with the arguments? and If the above technique doesn't do what I want after all, is there any other way to do this?

Blendfile

$\endgroup$
11
  • $\begingroup$ I deleted my answer since it does not seem to work. Another thing you can try is to set all function arguments. Set those you do not need to None (for objects) or 0 (for numberical values). $\endgroup$ – maddin45 May 9 '14 at 18:02
  • $\begingroup$ @maddin45 It seemed to work, but I had trouble getting the return value. I eventually tried this: object, hitpoint, normal = crosshair.rayCast(floor, crosshair, 0.0, "isTrackerFloor", 0, 1, 0), but object, hitpoint, and normal are all none (even with the cursor over the correct object)? Plus I only want/need the hitpoint. I also uploaded my .blend, in case that helps. $\endgroup$ – gandalf3 May 9 '14 at 19:14
  • $\begingroup$ yes that helps. What I have found out so far is that if you set the 'dist' attribute (for example to 100.0) you will at least get return values that are note none, but the values seem to be wrong. $\endgroup$ – maddin45 May 9 '14 at 19:39
  • $\begingroup$ @maddin45 I have a feeling something won't work, because if I understood the documentation correctly, the ray is fired towards the origin of the target object (so the location of the mouse won't affect the location of the intersection).. $\endgroup$ – gandalf3 May 9 '14 at 19:41
  • $\begingroup$ @maddin45 Is there any other way to make the ray only hit a specific object? I want to use an object which is not a plane, so the second method in the tutorial won't work. $\endgroup$ – gandalf3 May 9 '14 at 19:52
2
$\begingroup$

After some discussion with gandalf3 we found a solution:
The main problem was that the rayCast function will cast a ray between the centers of two objects: Those passed as objto and objfrom arguments. Thus the ray's hitpoint always was the position of objto, not the position over which the mouse hovered.

But rayCast also accepts 3D points as inputs. The trick is to use a Mouse sensor, set to 'Mouse Over Any', and connect it to the Python Controler which holds the script:
enter image description here

In the script one can use the rayTarget and raySource properties of the mouse over sensor as inputs for the rayCast funtion. The modified code looks as follows:

from bge import logic, render

render.showMouse(False)
#from bge

def main():
    scene = logic.getCurrentScene()
    cont = logic.getCurrentController()
    mouse_over = cont.sensors["mouse_over"]

    if mouse_over.positive:
        tracker = scene.objects["mainTarget"]
        crosshair = scene.objects["Cross_hair"]
        floor = scene.objects["Floor"]
        object, hitpoint, normal = crosshair.rayCast(mouse_over.rayTarget, mouse_over.raySource, 0.0, "isTrackerFloor", 0, 1, 0)
        tracker.worldPosition = hitpoint

One further note: The 'Edit Object' actuator which is set to 'Track To' seems to make the affected object point to the target with its local y-axis. Make sure the object with the actuator is rotated correctly in edit mode.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.