SceneKit radialGravity为何吸引物体后反向排斥,无法停在中心?
SceneKit径向重力场下物体抵达中心即被弹开的问题分析
现有基础配置
中心径向重力节点实现:
let gravityNode = SCNNode() let radialGravityField = SCNPhysicsField.radialGravity() gravityNode.physicsField = radialGravityField gravityNode.position = SCNVector3Make(0, 0, 0) radialGravityField.strength = 0.5 // 无论设为0.5还是9.8都会触发相同问题 scene.rootNode.addChildNode(gravityNode)
动态盒子节点实现:
let box = SCNBox(width: 0.5 , height: 0.5 , length: 0.5 , chamferRadius: CGFloat(0)) let boxNode = SCNNode(geometry: box) boxNode.geometry!.firstMaterial?.diffuse.contents = UIColor.red boxNode.position = <基于屏幕点击位置设置> boxNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil) boxNode.physicsBody?.mass = 1 scene.rootNode.addChildNode(boxNode)
问题产生原因
- 径向重力场的固有计算逻辑:径向重力的作用力方向始终沿物体与场中心的连线指向中心,力的大小与两点距离成反比。当物体运动到场中心(坐标为0,0,0)的瞬间,距离矢量的方向会直接反向——原本指向中心的吸引力,在物体穿过中心的一刹那会无过渡地变成方向相反的排斥力,不存在平滑的力衰减区间。
- 近距离力放大无限制:当前未给重力场设置最小作用距离,物体在向中心加速的过程中,越靠近中心受到的吸引力越强,最终会在抵达中心位置时积累出极高的线速度,不存在“缓慢减速停在中心”的状态,会直接高速冲过原点。
- 碰撞效果叠加放大:所有动态盒子的碰撞包围盒都会在中心位置重叠,高速冲过中心的盒子之间会发生硬碰撞,碰撞产生的冲量会进一步把物体往外推,最终形成“一到中心就被弹飞”的视觉效果。
对应调整方案
- 给径向重力场设置最小作用距离:配置
radialGravityField.minimumDistance = 0.5,该值略大于盒子的边长,当物体与中心的距离小于这个值时,重力强度不再持续增大,从根源上避免近距离加速度飙升的问题。 - 调整重力场的衰减参数:设置
radialGravityField.falloffExponent = 1,替换默认的平方衰减模式,避免近距离加速度随距离平方反比增长的问题,再根据实际效果微调strength值匹配预期的吸引力大小。 - 为动态物理体开启连续碰撞检测:配置
boxNode.physicsBody?.continuousCollisionDetectionThreshold = 0.1,避免物体高速运动时因为单帧位移过大出现穿模、碰撞响应异常的问题。 - 实现物体稳定停靠效果:给动态物理体设置合适的线性阻尼
linearDamping,让物体在向中心运动的过程中逐步减速,不会积累出能冲过中心的高速度,最终会在重力和阻尼的平衡作用下稳定停在中心位置。
内容的提问来源于stack exchange,提问作者Laurent Crivello
相关产品推荐
相关产品推荐

