我正在使用场景套件,我正在尝试制作第一人称游戏。我发现这个示例代码用于制作具有平移手势的第一人称相机。一切正常,但我不明白这里发生了什么。有人可以解释发生了什么吗?
func lookGestureRecognized(gesture: UIPanGestureRecognizer) {
//get translation and convert to rotation
let translation = gesture.translationInView(self.view)
let hAngle = acos(Float(translation.x) / 200) - Float(M_PI_2)
let vAngle = acos(Float(translation.y) / 200) - Float(M_PI_2)
//rotate hero
heroNode.physicsBody?.applyTorque(SCNVector4(x: 0, y: 1, z: 0, w: hAngle), impulse: true)
//tilt camera
elevation = max(Float(-M_PI_4), min(Float(M_PI_4), elevation + vAngle))
camNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: elevation)
//reset translation
gesture.setTranslation(CGPointZero, inView: self.view)
}
答案 0 :(得分:3)
以下是相同的代码,附加一些注释:
func lookGestureRecognized(gesture: UIPanGestureRecognizer) {
// Create Translation variable, containing the
// "distance" traveled by the finger since the last event
let translation = gesture.translationInView(self.view)
// From this distance, calculate how much the camera should move
// 1) horizontally, 2) vertically using angles (FPS controls)
let hAngle = acos(Float(translation.x) / 200) - Float(M_PI_2)
let vAngle = acos(Float(translation.y) / 200) - Float(M_PI_2)
// Apply the horizontal angle to the Hero node as a force to
// Make it rotate accordingly (physics body use forces to move)
heroNode.physicsBody?.applyTorque(SCNVector4(x: 0, y: 1, z: 0, w: hAngle), impulse: true)
// Use the other angle to look up and down, clamped to ±pi/4
elevation = max(Float(-M_PI_4), min(Float(M_PI_4), elevation + vAngle))
// Apply the new angle to teh camera on the X axis
camNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: elevation)
// Set the translation to 0 to avoid accumulation
// the next time the event is triggered
gesture.setTranslation(CGPointZero, inView: self.view)
}
这应该有助于理解,如果您需要有关其工作原理的详细信息,请与我们联系!
(注意:“距离”实际上是2D矢量)
编辑:这是对角度的更好解释:
let hAngle = acos(Float(translation.x) / 200) - Float(M_PI_2)
首先,平移(x上的像素距离)除以200.这既可以减慢运动速度,又可以(不安全地)将x保持在-1和1之间。
Acos给出一个值的弧余弦值。结果介于0到pi之间,(简化)仅适用于从-1到1的x。这是一个图表:http://www.wolframalpha.com/input/?i=acos%28x%29-pi%2F2
由于我们想要在正方向和负方向上移动,我们删除最大值的一半(M_PI_2,即pi / 2)以将结果保持在-pi / 2到pi / 2
最后,如果你在一个方向上移动手指200像素,你会在屏幕上看起来pi / 2 = 90°。