在 godot 中保持屏幕触摸

Holding screen touch in godot

我不确定我做事的方式是否正确,但我开始在 PC 上测试我的 3D 游戏草稿,然后我将它导出到 android。

首先,我希望我的播放器在我按住鼠标左键时跟随我的鼠标指针,所以我这样做了:

func _physics_process(delta):
    if Input.is_action_pressed("click"):
        position_2D = get_viewport().get_mouse_position()
        # then, project ray from camera to get a position_3D and move...

然后,当我想在Android上通过添加触摸屏支持来转换鼠标按钮时,我找到了InputEventScreenTouch,但在_physics_process中找不到如何使用它], 所以我把所有东西都放在 _input(event):

func _input(event):
    if event.is_action_pressed("click"):
        position_2D = get_viewport().get_mouse_position()
    elif event is InputEventScreenTouch and event.is_pressed():
        position_2D = get_viewport().get_canvas_transform().affine_inverse().xform(event.position)

问题是它只检测一次按下事件,所以不会为每一帧更新位置。

我想我需要把它放回 _physics_process,但由于我没有 event 实例,我不知道该怎么做。

有指示吗?也许我做错了。

首先,知道您可以通过触摸模拟鼠标输入,您会在项目设置 -> 输入设备 -> 指向中找到该选项。它不会进行多点触控,但这通常是更简单的方法。特别是如果您想保留 _physics_process 代码。


无论如何,让我们谈谈处理触摸输入。您需要注意两个事件:InputEventScreenTouchInputEventScreenDrag你错过了第二个。当然要保持鼠标支持InputEventMouse(有两种InputEventMouseButtonInputEventMouseMotion)。

事实上,我会在我的代码中这样做:

if !(event is InputEventScreenDrag)\
and !(event is InputEventScreenTouch)\
and !(event is InputEventMouse):
    return

对于多点触摸支持,您可以通过索引区分每个触摸。除了鼠标没有索引。概括地说,我们可以将鼠标视为索引 0,这导致我们这样做:

var touch_index = 0;
if !(event is InputEventMouse):
    touch_index = event.get_index()

要知道用户是否在拖动,你可以这样检查:

var is_drag = event is InputEventScreenDrag or event is InputEventMouseMotion

如果不是拖动,则为按下或释放事件。您可以通过检查 event.is_pressed() 来区分这两者。 我需要重申一下,event.is_pressed() 仅在 is_drag 为假时才相关。 让我这样说:

var is_drag = event is InputEventScreenDrag or event is InputEventMouseMotion
var is_press = !is_drag and event.is_pressed()
var is_release = !is_drag and !event.is_pressed()

顺便说一下,对于鼠标,您可以使用 button_mask 来确定按下了哪些按钮。例如:

var is_left_click = event is InputEventMouse\
                    and ((event as InputEventMouse).button_mask & BUTTON_LEFT) != 0

例如,如果您只想用左键单击来计数,您可能想将该逻辑添加到 is_press

最后 event.position 位置有效,即使是鼠标。而如果你想要一些CanvasItemNode2DControl)的局部坐标中的位置,你可以使用make_input_local.