Ios 将SCNNode旋转到面点

Ios 将SCNNode旋转到面点,ios,swift,scenekit,Ios,Swift,Scenekit,我试图旋转我的对象(SCNNode)以面对它移动的点。我只在x轴和y轴上移动,到目前为止我尝试了: // Action to move node let action1 = SCNAction.moveTo(SCNVector3(x: 4.0, y: 0.0, z: 6.0), duration: 3) // Get the tan angle: let angle = CGFloat(atan2(z, x)) if angle - previousAng

我试图旋转我的对象(SCNNode)以面对它移动的点。我只在x轴和y轴上移动,到目前为止我尝试了:

    // Action to move node
    let action1 = SCNAction.moveTo(SCNVector3(x: 4.0, y: 0.0, z: 6.0), duration: 3)
    // Get the tan angle:
    let angle = CGFloat(atan2(z, x))
    if angle - previousAngle > Pi {
        playerAngle += 2 * Pi
    } else if previousAngle - angle > Pi {
        playerAngle -= 2 * Pi
    }
    previousAngle = angle
    playerAngle = angle * RotationBlendFactor + playerAngle * (1 - RotationBlendFactor)
    let rot = playerAngle - 90 * DegreesToRadians
    flyNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: Float(rot))
它适用于某些目标点,但不适用于所有目标点

我还尝试添加到约束数组SCNLookAtConstraint,它完美地旋转了我的节点,但它阻止了我移动到动画:

    let targerNode = SCNNode()
    targerNode.position = SCNVector3(x: -4.0, y: 0.0, z: -2.0)
    let con = SCNLookAtConstraint(target: targerNode)
    flyNode.constraints = [con]        
    let action1 = SCNAction.moveTo(SCNVector3(x: 4.0, y: 0.0, z: -2.0), duration: 3)

你能帮我解决这个问题吗?

最简单的解决方案,尽管可能不是最优雅的,是将你的
移动到
操作
应用到一个节点,并将你的
移动约束
应用到该节点的子节点。这应该使两者都能在没有冲突的情况下运行。

尝试使用以下方法:(这是目标C,但应该很容易转换)

float x,z;//这些是您的变量,您可以分配这些变量以便删除此行
浮动偏移量=0;//用这个来抵消你的最终输出
//因为您的输出可能在
//四分之一圈左右,或更多
//但是一旦你得到了正确的偏移量
//这样它就会保持正确
浮子水曲度=1.570795;//因为scenekit使用弧度
//这需要是pi/2
//如果是华氏度,那就是90度
if(x<0){
offset+=aQuarterOfAturn;//将其旋转以补偿负x的缺失
x*=-1;//将x转换为正数,这样我们就可以计算它了
}
if(z<0){
offset+=aQuarterOfAturn;//将其旋转以补偿负z的缺失
z*=-1;//将z转换为正数,这样我们就可以计算它了
}
xzDelta=x+z//添加x和z
zPercent=z*100/xzDelta//所以我们可以计算出z的百分比
yRot=aQuarterOfAturn*zPercent/100//并最终将其转换为旋转
yRot+=偏移量//添加偏移量,现在就可以执行旋转
//请注意,此代码尚未测试,您可能需要对其进行偏移(如上所述)
//可能乘以负1
//如果它工作正常,但旋转被关闭了多少度,而不仅仅是偏移它
//如果它工作正常,但你向上移动,它向下旋转,那么将其乘以-1

让我知道它是如何工作的

听起来和我面临的问题很相似。看看这是否有帮助:@bpedit感谢我所追求的。那么最后一行看起来是否像
SCNAction.rotateTo(x:x,y:yRot,z:z,持续时间:1)
float x, z;// these are your vars you assign these so you can delete this line


float offset = 0; // use this to offset your final output
                  // because your output might be off by 
                  // a quarter of a turn or so, or more
                  // but once you got the offset right
                  // than it will stay right
float aQuarterOfAturn = 1.570795;// since scenekit uses radians
                                 // this needs to be pi/2
                                 // if it was degrees it would be 90


if (x < 0) {
    offset += aQuarterOfAturn;// turn it to compensate for the lack of negetive x
    x *= -1;// convert x to positive so we can calculate it
}
if (z < 0) {
    offset += aQuarterOfAturn;// turn it to compensate for the lack of negetive z
    z *= -1;// convert z to positive so we can calculate it
}

xzDelta = x + z// add x and z

zPercent = z * 100 / xzDelta // so we can calculate how much percent z is

yRot = aQuarterOfAturn * zPercent / 100 // and finally convert it to a rotation

yRot += offset // add the offset and you can implement the rotation now
// a note, this code has not been tested you may need to offset it (above)
// and possibly multiply it by negitive 1

// if it works fine but the rotation is off by however many degrees than just offset it

// if it works fine but your move up and it rotates down than multiply it by -1