Swift SCNIKConstraint是如何工作的?

Swift SCNIKConstraint是如何工作的?,swift,xcode,animation,scenekit,inverse-kinematics,Swift,Xcode,Animation,Scenekit,Inverse Kinematics,我有以下代码(这可以通过替换macOS游戏基础项目中的标准ViewController代码来运行): 根据我从文档中收集到的信息,动画(是的,场景套件视图动画设置设置为“在IB中播放和循环”)应通过旋转立方体将球体移动到y轴上尽可能靠近点2.0和-2.0的位置。然而,球体只是保持静止。我还尝试通过直接操纵球体和立方体的位置向量来设置它们的初始位置,而不是通过距离约束,但动画同样没有做任何操作 此外,我还尝试将“距离”约束与具有“注视”约束的长方体结合使用,使其旋转以不断注视球体-这导致长方体和球

我有以下代码(这可以通过替换macOS游戏基础项目中的标准ViewController代码来运行):

根据我从文档中收集到的信息,动画(是的,场景套件视图动画设置设置为“在IB中播放和循环”)应通过旋转立方体将球体移动到y轴上尽可能靠近点2.0和-2.0的位置。然而,球体只是保持静止。我还尝试通过直接操纵球体和立方体的位置向量来设置它们的初始位置,而不是通过距离约束,但动画同样没有做任何操作

此外,我还尝试将“距离”约束与具有“注视”约束的长方体结合使用,使其旋转以不断注视球体-这导致长方体和球体的渲染完全失控


我觉得这里的文档中可能遗漏了一些东西,比如另一个约束或设置某种初始值的某种变换矩阵。但是我在约束、动画和骨架方面遇到了一些其他问题,这让我开始相信SceneKit存在缺陷或一些未记录的方面。

您已经将sphereNode添加为boxNode的子节点。如果移动boxNode,则所有子对象也将移动,且约束无效。

要使IK约束在节点上工作,它必须是约束效应器的子对象,对吗?如中所示,IK的目标是boxNode,球体是其子节点,并将IK作为其约束之一。我不知道我正在移动提供的代码示例中的长方体节点,但是我可以看到距离约束确实在提供的范围内移动球体。如果没有距离约束或sphereNode的位置,球体与长方体位于同一位置,更改目标位置也不会对两者产生任何影响。检查此repo@OzgurSahin谢谢,该示例代码实际上非常有用。欢迎@Louis,这是Github中与scnikconstraint相关的唯一示例。
    let scene = SCNScene()
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    scene.rootNode.addChildNode(cameraNode)
    cameraNode.position = SCNVector3(x: 0, y: 0, z: 15)
    let lightNode = SCNNode()
    lightNode.light = SCNLight()
    lightNode.light!.type = .omni
    lightNode.position = SCNVector3(x: 0, y: 10, z: 10)
    scene.rootNode.addChildNode(lightNode)
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = .ambient
    ambientLightNode.light!.color = NSColor.darkGray
    scene.rootNode.addChildNode(ambientLightNode)

    /* RELEVANT CODE BEGINS */

    let boxGeo = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
    let boxMaterial = SCNMaterial()
    boxMaterial.diffuse.contents = NSColor.gray
    boxGeo.firstMaterial = boxMaterial
    let boxNode = SCNNode(geometry: boxGeo)
    scene.rootNode.addChildNode(boxNode)
    boxNode.name = "box0"

    let sphereGeo = SCNSphere(radius: 0.5)
    let sphereMaterial = SCNMaterial()
    sphereMaterial.diffuse.contents = NSColor.green
    sphereGeo.firstMaterial = sphereMaterial
    let sphereNode = SCNNode(geometry: sphereGeo)
    boxNode.addChildNode(sphereNode)
    sphereNode.name = "sphere0"

    sphereNode.constraints = [SCNConstraint]()

    let distance = SCNDistanceConstraint(target: boxNode)
    distance.minimumDistance = 2.0
    distance.maximumDistance = 5.0
    sphereNode.constraints?.append(distance)

    let ik = SCNIKConstraint.inverseKinematicsConstraint(chainRootNode: boxNode)
    sphereNode.constraints?.append(ik)

    let anim = CABasicAnimation(keyPath: "targetPosition.y")
    anim.fromValue = -2.0
    anim.toValue = 2.0
    anim.duration = 1
    anim.autoreverses = true
    anim.repeatCount = .infinity
    ik.addAnimation(anim, forKey: nil)

    /* RELEVANT CODE ENDS */

    let scnView = self.view as! SCNView
    scnView.scene = scene
    scnView.allowsCameraControl = true
    scnView.showsStatistics = true
    scnView.backgroundColor = NSColor.black