Auf dieser Seite

Qt Quick 3D Physik – Beispiel für einen CharacterController

Veranschaulicht den Typ „ CharacterController “.

Screenshot eines Testrums

Dieses Beispiel zeigt, wie man einen „ CharacterController “ verwendet, um die Kamera in einer Szene zu bewegen und so eine First-Person-Perspektive zu erzeugen. Der „ “ repräsentiert den Blickpunkt des Benutzers als Entität, die durch die physikalische Geometrie der Szene eingeschränkt ist, auf dem Boden läuft, Treppen hinauf- und hinuntersteigt und mit Triggern interagiert.

Die Szene

Die Szene besteht aus einem einfachen Gebäude, das in „Building.qml“ definiert ist und hier nicht im Detail erläutert wird. (Das Mesh- building.mesh wurde mit Blender erstellt. Es lässt sich mithilfe des Balsam-Tools aus der Datei „building.gltf“ nachbilden.)

Das Gebäude enthält drei Trigger:

  • Einen Trigger, der die Tür öffnet. Intern in „Building.qml“ implementiert
  • Ein „gravityField“-Trigger, der eine Eigenschaft inGravityField setzt, wenn sich etwas in seinem Bereich befindet.
  • Ein „teleport“-Trigger, der ein Signal an „ teleporterTriggered “ sendet, wenn etwas in ihn eintritt.

Der Charakter-Controller

Die vollständige Logik des Charakter-Controllers lautet wie folgt:

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 Charakter-Controller benötigt eine Form. Es wird ausschließlich „ CapsuleShape “ unterstützt. Beachten Sie, dass sich die Eigenschaft „height“ auf die Höhe des zylindrischen Teils der Kapsel bezieht: Die Gesamthöhe des Charakters wird durch Addition der Höhe der unteren und oberen Halbkugeln 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 ein „ TriggerBody “ auszulösen, muss bei der Charakter-Steuerung die Eigenschaft „ sendTriggerReports “ auf „ true “ gesetzt sein:

sendTriggerReports: true

CharacterController verfügt über eine eigene Eigenschaft „ gravity “, die unabhängig von „ PhysicsWorld “ ist. Ein häufiger Anwendungsfall ist das Umschalten zwischen Laufen und Fliegen. In diesem Beispiel implementieren wir ein Antigravitationsfeld, indem wir die Eigenschaft „ gravity “ so ändern, dass sie nach oben zeigt, wenn sich der Charakter innerhalb des Triggers „gravityField“ befindet:

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

Wenn das Signal „ teleporterTriggered “ ausgelöst wird, setzen wir die Position und Ausrichtung des Charakters auf seine Ausgangsposition zurück. Beachten Sie, dass die Eigenschaft „ position “ während der laufenden Simulation nicht geändert werden sollte. 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 des Charakters wird definiert, indem die Eigenschaft „ movement “ auf eine Geschwindigkeit gesetzt wird. Der Charakter versucht dann, sich mit dieser Geschwindigkeit relativ zum Vorwärtsvektor zu bewegen. Es kann jedoch vorkommen, dass sich der Charakter letztendlich mit einer anderen Geschwindigkeit bewegt, da er beispielsweise von einer Wand blockiert wird oder sich im freien Fall befindet. Maus- und Tastatureingaben stammen vom Objekt „ wasd “, einer abgespeckten Version von „ WasdController “.

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

Die beiden Drehachsen werden unterschiedlich behandelt, um der gängigen Praxis für WASD-Bewegungen beim Gehen auf dem Boden zu entsprechen:

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

Dateien:

Bilder:

© 2026 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.