Qt Quick 3D Physics - CharacterController の例

CharacterController タイプのデモです。

この例では、CharacterController を使用してシーン内のカメラを動かし、一人称視点で見る方法を示します。キャラクタコントローラは、シーンの物理的なジオメトリによって制約され、地面を歩き、階段を上り下りし、トリガと相互作用するエンティティとして、ユーザの視点を表します。

シーン

シーンはBuilding.qmlで定義されたシンプルなビルで構成されています。(メッシュbuilding.mesh はBlenderを使って作られました。balsamツールを使ってbuilding.gltfから再作成できます)。

建物には3つのトリガーがあります:

  • ドアを開けるトリガー。Building.qmlに内部実装されています。
  • gravityField "トリガーは、その中に何かがいるとき、プロパティinGravityField
  • テレポート(teleport)」トリガーは、何かがその中に入ると、シグナルteleporterTriggered

キャラクター・コントローラー

キャラクタ・コントローラの完全なロジックは以下の通りです:

CharacterController {
    id: character
    property vector3d startPos: Qt.vector3d(800, 175, -850)
    position: startPos
    function teleportHome() {
        character.teleport(character.startPos)
        wasd.cameraRotation.x = 180
    }

    collisionShapes: CapsuleShape {
        id: capsuleShape
        diameter: 50
        height: wasd.crouchActive ? 0 : 100
        Behavior on height {
            NumberAnimation { duration: 300 }
        }
    }
    property real characterHeight: capsuleShape.height + capsuleShape.diameter

    sendTriggerReports: true

    movement: Qt.vector3d(wasd.sideSpeed, 0, wasd.forwardSpeed)
    Behavior on movement {
        PropertyAnimation { duration: 200 }
    }

    gravity: building.inGravityField ? Qt.vector3d(0, 100, 0) : physicsWorld.gravity

    eulerRotation.y: wasd.cameraRotation.x
    PerspectiveCamera {
        id: camera
        position: Qt.vector3d(0, character.characterHeight / 2 - 10, 0)
        eulerRotation.x: wasd.cameraRotation.y
        clipFar: 10000
        clipNear: 10
    }
}

キャラクタコントローラにはシェイプが必要です。CapsuleShapeheightプロパティは、カプセルの円柱部分の高さを指すことに注意してください。キャラクタの全高は、底部と上部の半球の高さを足して計算されます:

collisionShapes: CapsuleShape {
    id: capsuleShape
    diameter: 50
    height: wasd.crouchActive ? 0 : 100
    Behavior on height {
        NumberAnimation { duration: 300 }
    }
}
property real characterHeight: capsuleShape.height + capsuleShape.diameter

TriggerBody をトリガするには、キャラクタ コントローラのsendTriggerReports プロパティがtrue に設定されている必要があります:

sendTriggerReports: true

CharacterController gravity PhysicsWorld一般的な使用例は、歩行と飛行を切り替えることです。この例では、キャラクタが「gravityField」トリガーの内側にいるときに、 プロパティを上向きに変更することで、反重力フィールドを実装しています:gravity

gravity: building.inGravityField ? Qt.vector3d(0, 100, 0) : physicsWorld.gravity
位置と移動

teleporterTriggered シグナルが発信されたら、キャラクタの位置と向きを初期位置に戻します。position プロパティは、シミュレーションの実行中には変更しないでください。代わりにteleport 関数を使用してください:

property vector3d startPos: Qt.vector3d(800, 175, -850)
position: startPos
function teleportHome() {
    character.teleport(character.startPos)
    wasd.cameraRotation.x = 180
}

キャラクタの動きは、movement プロパティを速度に設定することで定義します。キャラクタの動きは、 プロパティに速度を設定することで定義されます。キャラクタは、前方ベクトルに対して、その速度で移動しようとします。キャラクタは、壁に遮られたり、自由落下したりするため、最終的に異なる速度で移動することがあります。マウスやキーボードの入力は、WasdController の縮小版であるwasd オブジェクトから行います。

movement: Qt.vector3d(wasd.sideSpeed, 0, wasd.forwardSpeed)
Behavior on movement {
    PropertyAnimation { duration: 200 }
}

2つの回転軸は、地面を歩くときのWASD移動の一般的な慣習に従うために、異なる方法で処理されます:

  • 垂直方向の回転はビューの方向を変えますが、キャラクターを空中に飛ばしたり地面に掘り下げたりはしません
  • 水平方向の回転はキャラクターの前進方向を変える。(これは、物理シミュレーションの実行中にトランスフォームを変更してはいけないというルールの例外です:キャラクタコントローラの回転を変更しても、物理エンジンの状態は変わらないので大丈夫です。movement ベクトルの解釈が変わるだけです)
eulerRotation.y: wasd.cameraRotation.x
PerspectiveCamera {
    id: camera
    position: Qt.vector3d(0, character.characterHeight / 2 - 10, 0)
    eulerRotation.x: wasd.cameraRotation.y
    clipFar: 10000
    clipNear: 10
}

ファイル

画像

本ドキュメントに含まれる文書の著作権は、それぞれの所有者に帰属します 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。