Zylann / godot_heightmap_plugin

HeightMap terrain for Godot implemented in GDScript
Other
1.74k stars 160 forks source link

How can I detect where the player clicks ? #418

Open Naeta2 opened 9 months ago

Naeta2 commented 9 months ago

I am using the plugin to generate a world map, it is great thank you for it

I was trying to detect where the player mouse is relative to the terrain, I enabled collision but I can't find how to get a signal when the player mouse is on the terrain with data of where it is located. How can I access collision signals ?

Thank you

Zylann commented 9 months ago

Instead of signals, you can try using a raycast? See https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html

ElectronicRU commented 9 months ago

The terrain collider still calls set_ray_pickable to false despite the bug it works around being fixed in Godot 3.1. Maybe terrain can be ray-pickable now and we can have input_event support?

Zylann commented 9 months ago

I would still recommend using a raycast, because it offers similar functionality that works already.

Adding a ray_pickable property requires a extra work for a similar result which is more for convenience: it would require the terrain to also provide an _input_event, _mouse_enter, _mouse_exit methods, maybe also a capture_on_drag.

Unfortunately, it looks like the scripting API doesn't expose enough things for the plugin to offer the same functionality easily. For example, implementing _input_event_call requires to implement a C++ virtual method CollisionObject3D::_input_event_call which doesn't exist in GDScript. The plugin uses PhysicsServer3D directly, which does not provide the input callbacks part. Also, when you set ray_pickable to true, Godot's input system looks for a CollisionObject3D: https://github.com/godotengine/godot/blob/0bcc0e92b3f0ac57d4c4650722f347593a258572/scene/main/viewport.cpp#L900 Which means it wouldn't work with the terrain node, it is custom. The collision part would have to be completely re-implemented using nodes instead, just for that convenience feature...

On a side note, it seems GridMap and TileMap nodes (similar "terrain" nodes) could have the same issue in Godot itself. They don't have ray_pickable functionality, likely for the same reason. I could only find this proposal for GridMap, but it only fixes GridMap, it doesn't acknowledge the fact this is a general issue with all nodes that manage collision internally rather than relying on CollisionObject3D nodes.