在SceneKit游戏中为SCNNode动画SCNConstraint(LookAt)以使转换渐变

时间:2017-12-26 04:41:19

标签: ios swift scenekit scnnode

一般来说,当一个人想让游戏中的角色面对镜头时,可以使用SCNLookAtConstraint,这实际上也很适合我。

下面, my_object 是我尝试根据约束定位的节点。 '敌人'是指场景中的某个节点,而pointOfView是场景的视点。当我点击my_object它应该看一下敌人一小段时间,然后回到我的pointOfView。

设置LookAtConstraint以便'对象'看着敌人'一秒钟。

my_object.constraints?.removeAll()
let targetNode = sceneView.scene.rootNode.childNode(withName: (chosenScenarioForChallenge?.shape)!, recursively: true)
let lookAt = SCNLookAtConstraint(target: targetNode)
lookAt.isGimbalLockEnabled = true
my_object.constraints = [lookAt]                    
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(resetObject), userInfo: nil, repeats: false)

在查看“敌人”后重置对象以查看我的观点。节点

@objc
func resetObject() {
    my_object.constraints?.removeAll()
    let targetNode = sceneView.pointOfView
    let lookAt = SCNLookAtConstraint(target: targetNode)
    lookAt.isGimbalLockEnabled = true
    my_object.constraints = [lookAt]
    }

我的问题是,我不希望约束的变化突然发生。我希望它是平滑的,因此我想在这里加入动画。在查看SCNAction和SCNAnimation之后,我找不到任何与约束相关的内容。由于约束动态地更新位置,我可以理解SCNAction.move(to / by :)等不会起作用。最终,当我点击时,我的对象应该开始逐渐看到敌人的节点,经过1-2秒后,它应该回来看看我的pointOfView,这也是渐渐的。

请注意,我不希望角色在技术上看到相机,因此我使用的是SCNLookAtConstraint,而不是SCNBillboardConstraint。

指针会有所帮助,TIA。

3 个答案:

答案 0 :(得分:3)

target属性是读写的,因此您应该能够重用SCNLookAtConstraint实例(而不是创建新实例),只需交换目标。

修改

约束的influenceFactor允许节点的当前变换与约束计算的变换之间的动画更平滑。

答案 1 :(得分:1)

基于对@Managanese答案的测试,我可以说它有效,以某种方式 influenceFactor animationDuration 可以协同工作。我真的不明白,为什么 influenceFactor 的设置是必需的,它应该在没有设置的情况下也可以工作,但是不知何故。

我向其他遇到问题的人展示了代码示例( Swift 5.0,Xcode 11.2 ):

private func smoothlyLookAtTarget() {

    // influenceFactor and animationDuration work somehow together

    let constraint = SCNLookAtConstraint(target: targetNode)
    constraint.isGimbalLockEnabled = true
    constraint.influenceFactor = 0.1

    SCNTransaction.begin()
    SCNTransaction.animationDuration = 3.0
    cameraNode.constraints = [constraint]
    SCNTransaction.commit()
}

答案 2 :(得分:0)

另一种方法是使用外观约束将相机锁定到 cameraTargetNode,然后通过动画移动该节点,甚至在该节点上设置约束以保持与 target.position 的距离或复制 target.position。通过这种方式,您可以将相机约束上的影响设置为合适的软糖值。相机在其整个生命周期中保持其约束条件,您可以随意启用/禁用它。

这种方法的另一个好处是调试。您可以在开发过程中为 cameraTargetNode 提供您选择的几何体并跟踪摄像机目标,而无需推断或感受实际目标是什么。

我更进一步,使用了一个在 cameraNode 上设置了距离和加速度约束的 cameraMovementNode,它允许我看到外观和运动节点的位置。 Influence factor 和 isEnabled 在这里也很有帮助,因为您可以调整影响或禁用约束并单独保留约束目标。有时我注意到设置目标、更改/设置约束甚至将相机移入和移出树形图会导致奇怪的旋转和旋转。

通过我的方法,您可以将外观或目标移动到场景中的其他孩子,而不会出现任何奇怪的行为。通过这种方式,您可以通过操作/事务移动 moveMode,完成后,将其添加为目标的子项,并获得跟随和旋转目标。此外,reset() 可以处理从这些相机助手节点中清除约束,并根据需要将它们移动到场景的根。