クリックして移動

ℹ️ 留意事項

この記事は Godot 3から Godot 4 へ内容の書き換え中です。 Godot4では存在しない変数、関数が含まれている場合があります。もしその場合はリポジトリのIssuesまでご報告ください。

課題

クリックして指定した位置に3Dオブジェクトを移動させたい。

解決策

まず、世界として平面から始めてください。オブジェクトはこの平面上を移動します。

alt alt

このデモで使用するアクターは三角柱メッシュです。

alt alt

以下に移動動作のコードを示します。目標地点を指定すると、オブジェクトは向きを変えてその方向へ移動します。

extends CharacterBody3D

@export var speed = 5
@export var gravity = -5

var target = Vector3.ZERO

func _physics_process(delta):
    velocity.y += gravity * delta
    if target:
        look_at(target, Vector3.UP)
        rotation.x = 0
        velocity = -transform.basis.z * speed
        if transform.origin.distance_to(target) < .5:
            target = Vector3.ZERO
            velocity = Vector3.ZERO
    move_and_slide()

また、シーンに「マーカー」という名前の MeshInstance3D を追加しました。このオブジェクトは、クリックされた位置を示すために移動します。

alt alt

マウス→3D

現在、マウスの位置を3D空間にマッピングする手段が必要となります。スクリーンを3D世界の窓と見立てると、マウスは画面ガラス上に固定されています。3D空間で何かを選択するには、カメラ(視点)から出発し、マウスの位置を通って現実世界へと伸びるレイを投影しなければなりません。

これは手動でCamera3Dproject_rayメソッドを使用して行うことも可能ですが、以下のように、CollisionObject3Dノードがこの処理を自動的に行う特性を活用することもできます。必要なのは、StaticBody3Dグラウンドのinput_eventシグナルに接続することだけです。

func _on_StaticBody_input_event(camera, event, click_position, click_normal, shape_idx):
    if event is InputEventMouseButton and event.pressed:
        $Marker.transform.origin = click_position
        $Player.target = click_position

マーカーとプレイヤーのターゲットの位置をクリックされた位置に設定します。

alt alt

まとめ

この手法を使えば、3Dワールド内の任意のオブジェクトに対するクリックを検出できます。