Qt Quick 3D物理学 - 大砲の例

物理オブジェクトの生成方法を示します。

緑の風景を写したスクリーンショット。その中に、ピラミッド状に並んだ複数の赤いボックスがあり、ボックスを操作するためのスライダーが付いている。

この例では、必要に応じて物理オブジェクトを作成・削除する方法を示します。シーンは、いくつかの箱の積み重ねで構成されています。WASD とマウスを使って移動し、space を押すとボールを発射できます。

シーンは、ビュー、カメラ、ライトといったQt Quick の一般的な3Dオブジェクトで構成されています:

PerspectiveCamera {
    id: camera
    position: Qt.vector3d(-4000, 5000, 10000)
    eulerRotation: Qt.vector3d(-20, -20, 0)
    clipFar: 200000
    clipNear: 100
}
DirectionalLight {
    eulerRotation: Qt.vector3d(-45, 45, 0)
    castsShadow: true
    brightness: 1
    shadowMapQuality: Light.ShadowMapQualityVeryHigh
    shadowMapFar: camera.clipFar
    shadowFactor: 50
    csmNumSplits: 2
    csmSplit1: 0.1
    csmSplit2: 0.3
    softShadowQuality: Light.PCF4
}

また、静的な床も追加します:

StaticRigidBody {
    eulerRotation: Qt.vector3d(-90, 0, 0)
    collisionShapes: PlaneShape {}
    Model {
        source: "#Rectangle"
        scale: Qt.vector3d(2000, 2000, 1)
        materials: PrincipledMaterial {
            baseColor: "green"
        }
        castsShadows: false
        receivesShadows: true
    }
}

オブジェクトのスポナーとして使用するノードを作成し、その中にビューを配置します:

Node {
    id: shapeSpawner
    property var instancesBoxes: []
    property var instancesSpheres: []
    property int stackCount: 0
    property var boxComponent: Qt.createComponent("Box.qml")
    property var sphereComponent: Qt.createComponent("Sphere.qml")

    function createStack(stackZ, numStacks) {
        let size = 10
        let extents = 400

        for (let i = 0; i < size; i++) {
            for (let j = 0; j < size - i; j++) {
                let x = j * 2 - size + i
                let y = i * 2 + 1
                let z = 5 * (stackZ - numStacks)
                let center = Qt.vector3d(x, y, z).times(0.5 * extents)
                let box = boxComponent.incubateObject(shapeSpawner, {
                                                          "position": center,
                                                          "xyzExtents": extents
                                                      })
                instancesBoxes.push(box)
            }
        }
    }

    function createBall(position, forward) {
        const diameter = 600
        const speed = 20000
        let settings = {
            "position": position,
            "sphereDiameter": diameter
        }
        let sphere = sphereComponent.createObject(shapeSpawner, settings)
        sphere.setLinearVelocity(forward.times(speed))
        instancesSpheres.push(sphere)

        if (sphere === null) {
            console.log("Error creating object")
        }
    }

    function reset() {
        // Only run method if previous stack has been created fully
        for (let i = 0; i < instancesBoxes.length; i++)
            if (!instancesBoxes[i].object)
                return

        instancesSpheres.forEach(sphere => {
                                     sphere.collisionShapes = []
                                     sphere.destroy()
                                 })
        instancesBoxes.forEach(box => {
                                   box.object.collisionShapes = []
                                   box.object.destroy()
                               })
        instancesSpheres = []
        instancesBoxes = []

        for (let stackI = 0; stackI < stackSlider.value; stackI++) {
            shapeSpawner.createStack(stackI, stackSlider.value)
        }
    }
}

3つのメソッドがあります:スタックを作成するcreateStack 、速度を持ったボールを作成するcreateBall 、シーンをリセットするreset です。実際にスポーンされるボックスと球体は、それぞれのQMLファイル(box.qml およびsphere.qml )に格納されています。

ファイル:

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