Qt Quick 3D Physics - Exemple de CharacterController
Présente le type ` CharacterController `.

Cet exemple montre comment utiliser un ` CharacterController ` pour déplacer la caméra dans une scène, offrant ainsi une vue à la première personne. Le contrôleur de personnage représente le point de vue de l’utilisateur sous la forme d’une entité contrainte par la géométrie physique de la scène, qui marche au sol, monte et descend les escaliers, et interagit avec des déclencheurs.
La scène
La scène se compose d’un bâtiment simple défini dans Building.qml, qui ne sera pas expliqué en détail. (L’ building.mesh de maillage a été créé à l’aide de Blender. Il peut être recréé à partir du fichier building.gltf à l’aide de l’outil Balsam.)
Le bâtiment contient trois déclencheurs :
- Un déclencheur qui ouvre la porte. Implémenté en interne dans Building.qml
- Un déclencheur « gravityField » qui définit une propriété
inGravityFieldlorsqu'un élément se trouve à l'intérieur. - Un déclencheur « teleport » qui émet un signal
teleporterTriggeredlorsqu’un élément y pénètre.
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 la forme « CapsuleShape » est prise en charge. Notez que la propriété « height » fait référence à la hauteur de la partie cylindrique de la capsule : 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.diameterPour déclencher une « TriggerBody », le contrôleur de personnage doit avoir la propriété « sendTriggerReports » définie sur « true » :
sendTriggerReports: trueCharacterController dispose de sa propre propriété « gravity », indépendante de « PhysicsWorld ». Le cas d’utilisation courant consiste à basculer entre la marche et le vol. Dans cet exemple, nous implémentons un champ 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.gravityPosition et mouvement
Lorsque le signal « teleporterTriggered » est émis, nous ramenons la position et l’orientation du personnage à leur position initiale. Notez que la propriété « position » ne doit pas être modifiée pendant que la simulation est en cours. 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 attribuant une vitesse à la propriété ` movement `. Le personnage tentera alors de se déplacer à cette vitesse, par rapport au vecteur avant. Il peut toutefois finir par se déplacer à une vitesse différente, s’il est bloqué par un mur ou en chute libre. Les entrées souris/clavier proviennent de l’objet ` wasd `, qui est une version allégé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 les pratiques courantes en matière de déplacement WASD lors de la marche au sol :
- La rotation verticale modifie la direction de la vue, mais ne fait pas s’envoler le personnage ni ne l’enfonce dans le sol.
- La rotation horizontale modifie la direction d'avance 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 est sans risque de modifier la rotation du contrôleur de personnage, car cela ne modifie pas l'état du moteur physique : cela ne fait que modifier l'interprétation du vecteur d'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.