1

我想将状态机用于 Qt3D 中的实体对象并在其状态之间制作过渡动画。

我知道 QML 中的两个状态机框架:

  1. Qt 快速状态
  2. 声明式状态机框架

第一个框架内置在 QQuickItem 中,它是 QtQuick 中所有可视项目的基类。所以这些元素具有状态机的属性,如状态、转换等。由于Entity没有继承QQuickItem,我只能使用第二个框架。

我希望我的实体有两种状态:可见和隐藏。当它具有“隐藏”状态时,实体将缩小到 0。如果它可见,它将放大到 1。这是我当前使用声明性状态机框架实现的实体状态:

import Qt3D 2.0
import Qt3D.Renderer 2.0
import QtQml.StateMachine 1.0 as DSM

Entity {
    id: root

    property bool show: true

    components: [
        Transform {
            id: transform
            Scale { id: scale; scale: 1 }
            Translate { ... }
        }
        Mesh { ... },
        Material { ... },

    ]

    DSM.StateMachine {
        id: stateMachine
        initialState: visible
        running: true

        DSM.State {
            id: visible
            DSM.SignalTransition {
                targetState: hidden
                signal: showChanged
                guard: show == false
            }
            onEntered: scale.scale: 1
        }

        DSM.State {
            id: hidden
            DSM.SignalTransition {
                targetState: visible
                signal: showChanged
                guard: show == true
            }
            onEntered: scale.scale: 0
        }
    }
}

它有效,但我想在过渡之间添加动画。使用 Qt Quick States 我可以像这样使用 Transition 元素:

import QtQuick 2.5 as QQ2

Entity {
    ...
    transitions: QQ2.Transition {
            id: tr
            from: "visible"; to: "hidden"; reversible: true
            QQ2.NumberAnimation {
                target: scale
                property: "scale"
                duration: 500
                from: 1; to: 0
            }
        }
}

但我不能使用它,因为 Entity 和 DSM.StateMachine 以及 DSM 框架的其他部分都不包含transitions属性。

我只看到快速而肮脏的解决方案 - 将 NumberAnimation 元素添加到每个状态的 onEntered 插槽:

    DSM.State {
        id: visible
        onEntered: QQ2.NumberAnimation {
            target: scale; property: "scale"
            to: 1; duration: 1000
        }
    }

    DSM.State {
        id: hidden
        onEntered: QQ2.NumberAnimation {
            target: scale; property: "scale"
            to: 0; duration: 1000
        }
    }

有没有办法使用 Transition 或其他具有reversible属性的元素或某种方式来制作可逆动画,而无需为每个状态重新声明反向动画?

4

0 回答 0