- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
嘿,我有一个球,可以通过施加力来移动。我想让它做的基本上是在它通过空气到达目的地时,重力作用在它身上的因果效应。基本上,当“移动到” Action 正在播放时,重力不会产生影响,所以它不会慢慢落到地面,而是移动到它的最终位置,然后当“移动到” Action 停止时,它就会直接落下。对场景中的重力做。
我想让球以弧形抛出并落在目标上吗?
代码:
func CreateBall() {
let BallScene = SCNScene(named: "art.scnassets/Footballs.dae")
Ball = BallScene!.rootNode.childNodeWithName("Armature", recursively: true)! //the Amature/Bones
Ballbody = BallScene!.rootNode.childNodeWithName("Ball", recursively: true)!
let collisionCapsuleRadius3 = CGFloat(0.01) // Width of physicsBody
let collisionCapsuleHeight3 = CGFloat(0.01) // Height of physicsBody
Ball.position = SCNVector3Make(Guy.position.x, Guy.position.y, Guy.position.z)
Ball.scale = SCNVector3Make(5, 5, 5)
Ball.rotation = SCNVector4Make(0.0,0.0,0.0,0.0) // x,y,z,w
Ball.physicsBody = SCNPhysicsBody(type: .Dynamic, shape:SCNPhysicsShape(geometry: SCNCapsule(capRadius: collisionCapsuleRadius3, height: collisionCapsuleHeight3), options:nil))
Ball.physicsBody?.affectedByGravity = true
Ball.physicsBody?.friction = 1 //
Ball.physicsBody?.restitution = 0 //bounceness of the object. 1.0 will boounce forever
Ball.physicsBody?.angularDamping = 1 // ability to rotate
Ball.physicsBody?.mass = 1
Ball.physicsBody?.rollingFriction = 1
Ball.physicsBody!.categoryBitMask = BitmaskCollision4
Ball.physicsBody?.contactTestBitMask = BitmaskCollision3 //| BitmaskCollision2
Ballbody.physicsBody?.collisionBitMask = BitmaskCollision2 | BitmaskCollision3 | BitmaskCollision//| BitmaskCollision2
scnView.scene!.rootNode.addChildNode(Ball)
scnView.scene!.rootNode.addChildNode(Ballbody)
}
CreateBall()
现在这就是魔法发生的地方:
scnView.scene!.physicsWorld.gravity = SCNVector3(x: 0, y: -9.8, z: 0)
let location = SCNVector3(Guy2.presentationNode.position.x, 0.0, Guy2.presentationNode.position.z + Float(50) )
let moveAction = SCNAction.moveTo(location, duration: 2.0)
Ball.runAction(SCNAction.sequence([moveAction]))
let forceApplyed = SCNVector3(x: 0.0, y: 100.0 , z: 0.0)
Ball.physicsBody?.applyForce(forceApplyed, atPosition: Ball.presentationNode.position, impulse: true)
最佳答案
组合 SCNActions 和物理是行不通的,您需要使用其中之一。使用物理学,您可以计算出将节点推向目标所需的确切力。
我已经为 Unity 改编了一个解决方案 found here并利用了 SCNVector3 extension这使得一些计算变得更加容易。
基本上,您传入一个要抛出的 SCNNode
,一个用于目标的 SCNVector3
和一个您要抛出的 angle
(以弧度为单位)想要抛出节点。然后,此函数将计算出达到目标所需的力。
func shootProjectile() {
let velocity = ballisticVelocity(ball, target: target.position, angle: Float(0.4))
ball.physicsBody?.applyForce(velocity, impulse: true)
}
func ballisticVelocity(projectile:SCNNode, target: SCNVector3, angle: Float) -> SCNVector3 {
let origin = projectile.presentationNode.position
var dir = target - origin // get target direction
let h = dir.y // get height difference
dir.y = 0 // retain only the horizontal direction
var dist = dir.length() // get horizontal distance
dir.y = dist * tan(angle) // set dir to the elevation angle
dist += h / tan(angle) // correct for small height differences
// calculate the velocity magnitude
let vel = sqrt(dist * -scene.physicsWorld.gravity.y / sin(2 * angle))
return dir.normalized() * vel * Float(projectile.physicsBody!.mass)
}
同样重要的是将physicsBody的damping
设置为0,否则会受到空气阻力的影响。
我不会假装知道它到底是如何工作的,但维基百科上有文章解释了它背后的所有数学原理。
更新
自从使用上面的代码后,我注意到它并不总是有效,尤其是当原点和目标的高度不同时。从同一个论坛来看,这个功能似乎更可靠。
func calculateBestThrowSpeed(origin: SCNVector3, target: SCNVector3, timeToTarget:Float) -> SCNVector3 {
let gravity:SCNVector3 = sceneView.scene!.physicsWorld.gravity
let toTarget = target - origin
var toTargetXZ = toTarget
toTargetXZ.y = 0
let y = toTarget.y
let xz = toTargetXZ.length()
let t = timeToTarget
let v0y = y / t + 0.5 * gravity.length() * t
let v0xz = xz / t
var result = toTargetXZ.normalized()
result *= v0xz
result.y = v0y
return result
}
关于ios - 如何将 SCNAction 和冲量力应用于 SCNNode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39306792/
我的场景中有一系列(平面)节点,我需要它们始终面向相机。 如何调整变换/旋转以使其正常工作? 另外,我在哪里进行计算? 目前我正在尝试在 SCNSceneRendererDelegate render
我正在构建一个应用程序,它使用 Scenekit 根据从数据库返回的信息显示场景。我创建了一个带有类 func 的自定义类,它创建了一个包含所有需要绘制的 SCNNode 并将其返回到我的 SCNVi
我想从动画 SCNNode 获取当前节点位置我知道 presentationNode 并且我尝试从那里提取位置形式,但没有运气 这是我的代码 SCNNode * pelvis = [_unit chi
我正在使用 Swift 和 ARKit。我可以使用 ARSCNFaceGeometry、ARFaceTrackingConfiguration 等成功显示和更新面部网格。头部没有移动(它看起来向用户)
我有一个适用于 iOS 的 sceneKit 应用程序。我有一个连接到 SCNNode 的 SCNPhysicsBody。我将 .physicsBody 设置为 nil,对 SCNNode 进行一些更
我有一个 SCNNode 的子类“ExSCNNode”,用于向 SCNNode 添加更多属性和行为。 class ExSCNNode : SCNNode { ... } 我用 ExSCNNode 构建
我正在尝试将 SCNLight 添加到 SceneKit 中的 SCNSphere (SCNNode)。它的效果令人惊叹,唯一的问题是 SCNLight 所连接的源球体是完全黑色的,因为作为源,它根本
因此,我能够在 anchor 位置放置一个框节点。现在,如何旋转场景中的 SCNNode? 我正在尝试修改节点的变换和 eulerAngles,但它们没有任何效果: func renderer(_ r
有人知道如何将 SCNMaterial 转换为表面而不改变 SCNMaterial 包含图像的方向吗? 我想创建包含图像的 ARKit SCNNode,然后将其转换为表面,因为我想在所选位置的表面区域
我正在研究 ARKit 和图像检测。现在我有一个应用程序可以检测图像并将平面放置在屏幕上检测到的对象所在的位置。 我怎样才能在飞机上添加一个像按钮一样的可点击元素。我想在每个检测到的对象上都有一个点击
我正在通过编写一个游戏来学习 SceneKit,在这个游戏中你飞过小行星场躲避物体。最初,我通过移动/旋转相机来做到这一点,但我意识到在某些时候我会用完坐标空间,最好将所有对象移向相机(并在我完成后处
我正在处理枢轴和位置已更改的子节点。我发现了很多SCNNode转换主题,但似乎没有一个能代表我的情况。 我有六个球:(不能发布超过 2 个链接,图片位于 i.stack.imgur.com/v3Lc4
我正在使用 Apple 的 SceneKit 并拥有自定义 .dae 资源。我已将资源转换为 .scn 文件。我正在从 .scn 文件中按名称获取 SCNNode。将 SCNNode 作为子节点放置在
我有以下情况。一个 SCNView,其中显示了一座桥的 .scn。在屏幕的左侧,您可以看到桥梁的视觉表示。 我想做以下事情。 在“模型浏览器”左侧选择一项 缩放到所选项目并聚焦 在提供的屏幕截图上。你
我在 SwiftUI 框架内的“SCNView”中有一个“SCNCylinder”。我的目标是围绕不同的轴并以不同的角度旋转圆柱体。我有两个(某种意义上的)按钮,它们接受用户的 180° 或 90°
我试图通过将其枢轴点设置为任何角来旋转 block ,但似乎设置枢轴点实际上重新定位了节点,使该点保持在原来的位置...... 例如 SCNBox *box = [SCNBox boxWithWidt
假设我有 2 个 SCNNodes node1 和 node2。 我希望 node1 的位置为 node1.position = SCNVector3(0, 0, 0) 我希望 node2 的位置为
我正在使用下面的代码创建一个盒子放置在我的 AR 场景中: let box = SCNBox(width: side, height: side, length: side, chamferRadiu
问题: 我试图让一个节点看着手机,无论手机的方向如何,节点的顶部始终指向手机的北极。假设节点位于中心,手机从 (0, 0, 10) 开始,并假设节点具有类似于手机的矩形几何形状。我希望该矩形的顶部始终
我有一个 scnnode,我使用 UIPanGestureRecognizer 围绕它的 Y 轴旋转。这很好,但我想对化身应用惯性,以便在用户抬起手指后它会一直旋转(并减速),有点像 ScrollVi
我是一名优秀的程序员,十分优秀!