Qt Quick Physique 3D - Exemple de CharacterController
Démonstration du type CharacterController.

Cet exemple montre comment utiliser un CharacterController pour déplacer la caméra dans une scène, en donnant une vue à la première personne. Le contrôleur de personnage représente le point de vue de l'utilisateur en tant qu'entité contrainte par la géométrie physique de la scène, qui marche sur le sol, monte et descend des escaliers et interagit avec des déclencheurs.
La scène
La scène consiste en un simple bâtiment défini dans Building.qml, qui ne sera pas expliqué en détail. (Le maillage building.mesh a été réalisé avec Blender. Il peut être recréé à partir de building.gltf en utilisant l'outil balsam ).
Le bâtiment contient trois triggers :
- Un déclencheur qui ouvre la porte. Implémenté en interne dans Building.qml
- Un trigger "gravityField" qui définit une propriété
inGravityFieldlorsque quelque chose se trouve à l'intérieur. - Un trigger "teleport" qui émet un signal
teleporterTriggeredlorsque quelque chose entre dans le bâtiment.
Le contrôleur de personnage
La logique complète du contrôleur de personnage est la suivante :
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 } }
Le contrôleur de personnage a besoin d'une forme. Seule CapsuleShape est prise en charge. La hauteur totale du personnage est calculée en additionnant la hauteur des hémisphères inférieur et supérieur :
collisionShapes: CapsuleShape { id: capsuleShape diameter: 50 height: wasd.crouchActive ? 0 : 100 Behavior on height { NumberAnimation { duration: 300 } } } property real characterHeight: capsuleShape.height + capsuleShape.diameter
Pour déclencher un TriggerBody, le contrôleur de caractères doit avoir la propriété sendTriggerReports définie sur true:
sendTriggerReports: true
CharacterController a sa propre propriété gravity, indépendante de PhysicsWorld. Le cas d'utilisation le plus courant est de passer de la marche au vol. Dans cet exemple, nous mettons en œuvre un champ d'antigravité en modifiant la propriété gravity pour qu'elle pointe vers le haut lorsque le personnage se trouve à l'intérieur du déclencheur "gravityField" :
gravity: building.inGravityField ? Qt.vector3d(0, 100, 0) : physicsWorld.gravity
Position et mouvement
Lorsque le signal teleporterTriggered est émis, nous ramenons la position et l'orientation du personnage à sa position initiale. Notez que la propriété position ne doit pas être modifiée lorsque la simulation est en cours d'exécution. Utilisez plutôt la fonction teleport:
property vector3d startPos: Qt.vector3d(800, 175, -850) position: startPos function teleportHome() { character.teleport(character.startPos) wasd.cameraRotation.x = 180 }
Le mouvement du personnage est défini en fixant la propriété movement à une vitesse. Le personnage essaiera alors de se déplacer à cette vitesse, par rapport au vecteur avant. Le personnage peut se déplacer à une vitesse différente, car il peut être bloqué par un mur ou être en chute libre. L'entrée souris/clavier provient de l'objet wasd, qui est une version simplifiée de WasdController.
movement: Qt.vector3d(wasd.sideSpeed, 0, wasd.forwardSpeed) Behavior on movement { PropertyAnimation { duration: 200 } }
Les deux axes de rotation sont gérés différemment, afin de respecter la pratique courante des mouvements WASD lorsque l'on marche sur le sol :
- La rotation verticale modifie la direction de la vue, mais ne permet pas au personnage de s'élever dans les airs ou de s'enfoncer dans le sol.
- La rotation horizontale modifie la direction vers l'avant du personnage. (Il s'agit d'une exception à la règle selon laquelle les transformations ne doivent pas être modifiées lorsque la simulation physique est en cours : Il n'y a aucun risque à modifier la rotation du contrôleur du personnage, puisque cela ne change pas l'état du moteur physique : cela change seulement l'interprétation du vecteur 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 }
Fichiers :
- charactercontroller/Building.qml
- charactercontroller/CMakeLists.txt
- charactercontroller/Wasd.qml
- charactercontroller/charactercontroller.pro
- charactercontroller/main.cpp
- charactercontroller/main.qml
- charactercontroller/qml.qrc
Images :
- charactercontroller/maps/Tape001_1K_Color.jpg
- charactercontroller/maps/Tape001_1K_NormalGL.jpg
- charactercontroller/maps/Tape001_1K_Roughness.jpg
- charactercontroller/maps/Tiles107_1K_Color.jpg
- charactercontroller/maps/Tiles107_1K_NormalGL.jpg
- charactercontroller/maps/Tiles107_1K_Roughness.jpg
- charactercontroller/maps/Tiles108_1K_Color.jpg
- charactercontroller/maps/sign.png
- charactercontroller/maps/sphere.png
© 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.