如何在 godot 4.1 中获取 3D 鼠标位置?我尝试过的所有方法都不起作用,而且所有 YT 教程都不起作用!
我尝试过使用文档和 YT 教程。我希望它能起作用!!!
我认为这是 godot 中 intersect_ray() 函数的问题,因为它只允许 1 个参数而不是 2 个。
您一定正在看Godot 3 教程。请注意,由于 Godot 2 非常小众,因此在 Godot 4 之前发布的许多 Godot 3 教程都没有指定它们是哪个版本的 Godot。
关于文档:您可以在左下角以及 URL 中找到您正在阅读文档的 Godot 版本。
根据
intersect_ray
,概念是相同的,但API不同。特别是:在 Godot 3 中,intersect_ray
需要许多可选参数。 Godot 4 的 Bug,它们被统一为一个对象。
所以在 GODOT 3 中你会做这样的事情:
var space_state := get_world().direct_space_state
var result := space_state.intersect_ray(origin, end)
您可以查看 Godot 3 中
intersect_ray
的文档以了解额外的参数。文章光线投射(Godot 3)有进一步的解释。
GODOT 4 中也是这样:
var space_state := get_world_3d().direct_space_state
var query := PhysicsRayQueryParameters3D.create(origin, end)
var result := space_state.intersect_ray(query)
PhysicsRayQueryParameters3D
类以获取额外的属性。文章光线投射(Godot 4)有进一步的解释。
要获取鼠标在 Godot 4 中悬停的 3D 位置,首先需要获取鼠标位置和当前位置
Camera3D
:
var viewport := get_viewport()
var mouse_position := viewport.get_mouse_position()
var camera := viewport.get_camera_3d()
然后我们就可以得到该点的射线原点和方向:
var origin := camera.project_ray_origin(mouse_position)
var direction := camera.project_ray_normal(mouse_position)
由于我们需要原点和终点,因此我们使用原点、方向和射线的最大长度来计算终点...让我们使用
far
中的 Camera3D
作为射线的长度:
var ray_length := camera.far
var end := origin + direction * ray_length
当然,让我们使用
intersect_ray
:
var space_state := get_world_3d().direct_space_state
var query := PhysicsRayQueryParameters3D.create(origin, end)
var result := space_state.intersect_ray(query)
当然,请阅读立场:
var mouse_position_3D:Vector3 = result["position"]
这提醒我,如果没有交集,你会得到一个空的
Dictionary
,让我们来处理这个:
var mouse_position_3D:Vector3 = result.get("position", end)
这里,如果结果为空(因此没有
"position"
键),您将得到射线的末端作为位置。
知道如果你想通过其他方式处理这个问题,你可以检查结果是否为空:
var mouse_position_3D := end
if not result.is_empty():
mouse_position_3D = result["position"]
此外,您可以写
result.position
而不是 result["position"]
,但我在这里使用后者来强调它是 Dictionary
中的关键。
当然,您可以使代码更短(我将其分解为简单的步骤以进行解释)。您可以使用更合理的光线长度。也许缓存
viewport
这样你就不必每次调用都获取它......(你只需要当运行此代码的 Node
进入场景树时获取它)。
事实上,您可以在
get_world_3d
上使用 Viewport
,以防您不想在 Node3D
上运行此代码:
var space_state := viewport.get_world_3d().direct_space_state
当然,您可以配置
PhysicsRayQueryParameters3D
来排除对象、与附加(或代替)实体相交的区域以及具有特定的碰撞遮罩。