Qt Quick 3D Physics - CharacterController Beispiel

Demonstriert den Typ CharacterController.

Dieses Beispiel zeigt, wie eine CharacterController verwendet wird, um die Kamera in einer Szene zu bewegen und eine Ich-Perspektive zu ermöglichen. Der CharacterController repräsentiert den Blickwinkel des Benutzers als eine Entität, die durch die physikalische Geometrie der Szene eingeschränkt ist, auf dem Boden geht, Treppen hinauf/hinunter steigt und mit Triggern interagiert.

Die Szene

Die Szene besteht aus einem einfachen Gebäude, das in Building.qml definiert ist und nicht näher erläutert wird. (Das Mesh building.mesh wurde mit Blender erstellt. Es kann mit dem Balsam-Tool aus building.gltf neu erstellt werden).

Das Gebäude enthält drei Auslöser:

  • Ein Auslöser, der die Tür öffnet. Intern implementiert in Building.qml
  • Ein "gravityField"-Trigger, der eine Eigenschaft inGravityField setzt, wenn sich etwas darin befindet.
  • Ein "Teleport"-Auslöser, der ein Signal teleporterTriggered aussendet, wenn jemand das Gebäude betritt.

Der Charakter-Controller

Die komplette Logik der Zeichensteuerung sieht wie folgt aus:

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
    }
}

Der Zeichen-Controller benötigt eine Form. Nur CapsuleShape wird unterstützt. Beachten Sie, dass sich die Eigenschaft height auf die Höhe des zylindrischen Teils der Kapsel bezieht: die Gesamthöhe der Figur wird durch Addition der Höhe der unteren und oberen Halbkugel berechnet:

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

Um eine TriggerBody auszulösen, muss die Eigenschaft sendTriggerReports der Zeichensteuerung auf true gesetzt sein:

sendTriggerReports: true

CharacterController Die Ameise hat ihre eigene Eigenschaft gravity, unabhängig von PhysicsWorld. Der übliche Anwendungsfall ist das Umschalten zwischen Gehen und Fliegen. In diesem Beispiel implementieren wir ein Antigravitationsfeld, indem wir die Eigenschaft gravity so ändern, dass sie nach oben zeigt, wenn sich die Figur innerhalb des "gravityField"-Triggers befindet:

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

Wenn das Signal teleporterTriggered ausgesendet wird, ändern wir die Position und die Ausrichtung der Figur zurück in ihre Ausgangsposition. Beachten Sie, dass die Eigenschaft position nicht geändert werden sollte, während die Simulation läuft. Verwenden Sie stattdessen die Funktion teleport:

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

Die Bewegung der Figur wird definiert, indem die Eigenschaft movement auf eine Geschwindigkeit gesetzt wird. Die Figur wird dann versuchen, sich mit dieser Geschwindigkeit zu bewegen, relativ zum Vorwärtsvektor. Die Figur kann sich am Ende mit einer anderen Geschwindigkeit bewegen, da sie durch eine Wand blockiert sein kann oder sich im freien Fall befindet. Die Maus-/Tastatureingabe erfolgt über das Objekt wasd, das eine abgespeckte Version von WasdController ist.

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

Die beiden Rotationsachsen werden unterschiedlich gehandhabt, um der üblichen Praxis der WASD-Bewegung beim Gehen auf dem Boden zu folgen:

  • Die vertikale Drehung ändert die Blickrichtung, lässt die Figur aber nicht in die Luft fliegen oder sich in den Boden eingraben.
  • Die horizontale Drehung ändert die Vorwärtsrichtung der Figur. (Dies ist eine Ausnahme von der Regel, dass Transformationen nicht geändert werden sollten, während die Physiksimulation läuft: Es ist unbedenklich, die Rotation des Charakter-Controllers zu ändern, da dies den Zustand der Physik-Engine nicht verändert: Es ändert nur die Interpretation des movement Vektors).
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
}

Dateien:

Bilder:

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.