![]() |
Attention | Topic was automatically imported from the old Question2Answer platform. |
![]() |
Asked By | grok |
The set-up is very basic, I want to use ray casting to pick a kinematic body. Think about having two eggs, one is called Fred and one Joe. A kid clicks on one of them, did he clicked on Joe or Fred? All this I need done via ray casting.
So I want to print the instance name of a clicked node. I don’t know how to use the resource id returned by the raycast space_state.intersect_ray(ray_from, ray_to), there seem to be no way to connect those IDs to “body1” or “body2”. Any ideas?
extends Spatial
var RAY_LENGTH = 1000
const Body = preload("res://example5/KinematicBody.tscn")
func _ready():
var body1 = Body.instance()
body1.set_name("body1")
add_child(body1)
body1.translate(Vector3(-10, 0, 0))
var body2 = Body.instance()
body2.set_name("body2")
add_child(body2)
body2.translate(Vector3(10, 0, 0))
return
func _input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_LEFT and event.pressed:
var hits = get_object_under_mouse()
print("Hit:", hits)
if hits:
print(hits.collider.name)
return
# cast a ray from camera at mouse position, and get the object colliding with the ray
func get_object_under_mouse():
var mouse_pos = get_viewport().get_mouse_position()
var ray_from = $Camera.project_ray_origin(mouse_pos)
var ray_to = ray_from + $Camera.project_ray_normal(mouse_pos) * RAY_LENGTH
var space_state = get_world().direct_space_state
var selection = space_state.intersect_ray(ray_from, ray_to)
return selection
Result:
Hit:{collider:[KinematicBody:1180], collider_id:1180, normal:(0, 0.032928, 0.999458), position:(-9.748708, 0.295415, 0.99081), rid:[RID], shape:0}
KinematicBody
Hit:{collider:[KinematicBody:1184], collider_id:1184, normal:(0.001229, 0.031697, 0.999497), position:(9.453918, 0.492391, 0.988022), rid:[RID], shape:0}
KinematicBod
What I want to output is “body1” when I click on it.
Edit
Thanks for helping me, I figured it out. It was a scene hierarchy problem. The code above is fine. In the KinematicBody scene I used an empty Spatial node as the scene root. That means that the raycast collision event is correctly captured by the physics engine to the second node in the hierarchy, the actual KinematicBody node. That is because this node is interacting physically with the ray cast, not Spatial. If one moves the KinematicBody to the top as the root of the instanced scene, then the sript will return correctly body1 or body2.
To keep the Spatial node as your scene root, since the reference to the cinematic objects is set, one could simply go up the node hierarchy.
if hits:
print(hits.collider.name)
var c = hits.collider
print (c.get_parent().name)
my set up is different than yours but I can print a selection as kinematicbody:1404 , my selection variable name is item if I print “item.name” it prints “PlayerJeep”. that is the equivalent of the first entry in the library your printing.name “KinematicBody:1184.name”
I dont have enough experience to know it would work but I would try something like “print(collider[0].name)” and see if that gets what you are looking for.
ArthurER | 2020-10-05 19:03
Thats what print(hits.collider.name) was doing, but it prints the Scene’s node name (KinematicBody), while I need the instance name (“body1” or “body2”). So far I have no way of knowing which instance of Body I clicked.
grok | 2020-10-05 20:00