如何在godot 4.1中获取3D鼠标位置?

问题描述 投票:0回答:1

如何在 godot 4.1 中获取 3D 鼠标位置?我尝试过的所有方法都不起作用,而且所有 YT 教程都不起作用!

我尝试过使用文档和 YT 教程。我希望它能起作用!!!

我认为这是 godot 中 intersect_ray() 函数的问题,因为它只允许 1 个参数而不是 2 个。

3d gdscript godot4
1个回答
0
投票

您一定正在看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
来排除对象、与附加(或代替)实体相交的区域以及具有特定的碰撞遮罩。

© www.soinside.com 2019 - 2024. All rights reserved.