En esta página

Qt Quick 3D Physics - Ejemplo de CharacterController

Demuestra el tipo CharacterController.

Captura de pantalla de una sala de pruebas

Este ejemplo muestra cómo utilizar un CharacterController para mover la cámara en una escena, dando una vista en primera persona. El controlador de personaje representa el punto de vista del usuario como una entidad que está constreñida por la geometría física de la escena, camina por el suelo, sube/baja escaleras e interactúa con disparadores.

La escena

La escena consiste en un edificio simple que se define en Building.qml, y no se explicará en detalle. (La malla building.mesh fue hecha usando Blender. Puede recrearse a partir de building.gltf utilizando la herramienta balsam ).

El edificio contiene tres disparadores:

  • Un disparador que abre la puerta. Implementado internamente en Building.qml
  • Un trigger "gravityField" que establece una propiedad inGravityField cuando hay algo dentro de él.
  • Un trigger "teleport" que emite una señal teleporterTriggered cuando algo entra en él.

El controlador de personajes

La lógica completa del controlador de personajes es la siguiente:

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

El controlador de caracteres necesita una forma. Sólo se admite CapsuleShape. Ten en cuenta que la propiedad height se refiere a la altura de la parte cilíndrica de la cápsula: la altura total del personaje se calcula sumando la altura de los hemisferios inferior y superior:

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

Para activar un TriggerBody, el controlador de caracteres debe tener la propiedad sendTriggerReports establecida en true:

sendTriggerReports: true

CharacterController tiene su propia propiedad gravity, independiente de PhysicsWorld. El caso de uso común es cambiar entre caminar y volar. En este ejemplo, implementamos un campo antigravedad cambiando la propiedad gravity para que apunte hacia arriba cuando el personaje esté dentro del trigger "gravityField":

gravity: building.inGravityField ? Qt.vector3d(0, 100, 0) : physicsWorld.gravity
Posición y movimiento

Cuando se emite la señal teleporterTriggered, cambiamos la posición y orientación del personaje a su posición inicial. Ten en cuenta que la propiedad position no debe modificarse mientras se ejecuta la simulación. Utilice en su lugar la función teleport:

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

El movimiento del personaje se define estableciendo la propiedad movement a una velocidad. El personaje intentará moverse con esa velocidad, relativa al vector de avance. El personaje puede terminar moviéndose a una velocidad diferente, ya que puede ser bloqueado por una pared, o estar en caída libre. La entrada del ratón/teclado proviene del objeto wasd, que es una versión reducida de WasdController.

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

Los dos ejes de rotación se manejan de forma diferente, con el fin de seguir la práctica común para el movimiento WASD al caminar sobre el suelo:

  • La rotación vertical cambia la dirección de la vista, pero no hace que el personaje vuele por los aires o se hunda en el suelo.
  • La rotación horizontal cambia la dirección de avance del personaje. (Esta es una excepción a la regla de que las transformaciones no deben cambiarse cuando la simulación física está en marcha: Es seguro cambiar la rotación del controlador del personaje, ya que eso no cambia el estado del motor de física: sólo cambia la interpretación del vector 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
}

Archivos:

Imágenes:

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