SceneKit的物理引擎是很强大的, 你只需要告诉引擎你想使用的物理学效果, 接下来的一切都有引擎来完成, 模拟重力, 检测碰撞等.
在进行物理仿真模拟之前先来解释下几个概念.
首先, 力的作用的相互的, 当两个物体之间进行力的作用时情况是多样的, 可能两者都有运动, 也可能只有其中的一个会运动, 试想, 如果拿一个鸡蛋去碰撞一块很大的石头, 很显然, 鸡蛋碎了, 石头不会有任何变化(以我们肉眼来观察, 石头是不会有变化的, 实质上石头是有变化的), 物理仿真中的type就是为了定义当一个物体受到力的作用时该如何去响应.
static
静态物体不会移动:当其他物体可能与这些物体碰撞时,静态物体本身不受模拟中的任何力和碰撞的影响。 你可以使用这种类型的墙壁和大块不动的巨石。
dynamic
动力体受力量和碰撞的影响; 您可以使用这种类型的东西,如活动椅子,桌子和杯子。
kinematic
运动体类似于静态体,因为它们也不受影响
力量和碰撞 但是,您可以移动这些类型,并且它们也可能与动态主体相冲突。 您可以使用这种类型的身体,例如移动电梯或可以打开和关闭的门。
在SceneKit中所有的物理对象都是SCNPhysicsBody
, 然后需要把该对象绑定到SCNNode的physicsBody实例属性, 然后物理引擎就可以进行仿真模拟了.
在上一节中, 我们使用Node去管理一个几何体, 同样, SCNPhysicsBody对象也管理者物理引擎, 也就是说, 此时我们的node拥有一个可以做物理仿真模拟的几何体
在let geometryNode = SCNNode(geometry: geometry)
下面添加如下代码
geometryNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
创建物理体时,您可以指定物体应具有的类型和形状。 如果为nil,Scene Kit将根据节点的几何形状自动生成一个形状。
接下来运行工程, 千万不要眨眼, 你会发现一个立方体很快的掉落下来, 然后消失.
接下来我们需要修改下视角, 让物体受重力作用更明显一些.
修改下面的代码
cameraNode.position = SCNVector3(x: 0, y: -5, z: 10)
再次运行, 会看到一个物体从顶部掉下来
自由落体实现了, 接下来我们给该物体添加一个向上的推力
让物体实现一个抛物线的自由落体运动
在geometryNode.physicsBody = SCNPhysicsBody(type: .dynamic, shape: nil)
下面添加如下代码
这个设置我们的物体要移动的重点位置, 下面三个值得意思是, x为0, 代表从中心带开始运动, y值为正数, 代表向上, z为0代表我们看的视角的深度不会变, 如果是负数, 则会发现在运动过程中, 物体越来越小, 如果为正, 则发现在运动过程中物体则会运来越大
let force = SCNVector3(x: 0, y: 15 , z: 0)
作用力的位置
let position = SCNVector3(x: 0.05, y: 0.05, z: 0.05)
给节点上的几何体添加一个作用力, 当您向物理机构施加力量时,您可以使用applyForce(_:atPosition:impluse :),并将SCNVector3的实例传递给要施加该力的力和位置,以及是否强制将被用作冲动。您应用的力将影响物理体的线性和角加速度。
geometryNode.physicsBody?.applyForce(force, at: position, asImpulse: true)
注意
刚刚为了观察自由落体效果, 我们把视角修改了, 让物体从顶部掉落, 现在需要把它再改回来, 让其从底部出现
cameraNode.position = SCNVector3(x: 0, y: 5, z: 10)
OK, 运行工程, 会发现有一个几何体从底部向上抛, 然后在做自由落体运动
关与力的一些解释
物理仿真中的力使用的是向量表示的, 向量是有方向有距离的一个值.
运行使用真机, 模拟器很卡
网友评论