I am trying to simulate a pinball game and I want to use PhysicsBody & PhysicsMotion to achieve that. I tuned the parameters around in PhysicsBodyComponent, but the result is not quite ideal for now.
Imagine a fully inflated basketball bouncing high off the ground (ground vs basketball). I assign PhysicsBodyComponent
and CollisionComponent
to both basketball and the ground.
For basket ball, I set it as:
- dynamic mode
- mass 1, inertia .one
- Material.Restitution 1
- Angular Damping and Linear Damping to 0
- AddForce to make the basketball move to hit the ground
For ground, I set it as:
- static mode
- mass 1, inertia .zero
- Material.Restitution 1
- Angular Damping and Linear Damping to 0
However, when the basket ball hit the ground, it isn't that bouncy, the basketball behaves like hitting to a cotton and the linear speed just dumps fast. Wonder how I could achieve the bouncing effect like real basketball vs ground.
I'm surprised to hear you don't get more bounce. Without seeing all the code it's hard to tell why. Here's a rough example of a simulation for a basketball on an indoor court. I did some research to find the correct input parameters to supply to PhysicsBodyComponent. A higher restitution will result in more bounce. Tap on the ball to see it bounce. Hopefully that points you in the right direction. If it doesn't, please reply with a focused code sample so I can better help.
struct ImmersiveView: View {
var body: some View {
RealityView { content in
let root = Entity()
let floor = ModelEntity(mesh: .generatePlane(width: 15, depth: 28), materials: [SimpleMaterial(color: .brown, isMetallic: false)])
let ballRadius:Float = 0.121
let ball = ModelEntity(mesh: .generateSphere(radius: ballRadius), materials: [SimpleMaterial(color: .orange, isMetallic: false)])
// Make sure to set the appropriate collision shape
ball.components.set(CollisionComponent(shapes: [.generateSphere(radius: ballRadius)]))
ball.components.set(InputTargetComponent())
ball.position = [0, 0, -4.0]
floor.generateCollisionShapes(recursive: false)
ball.generateCollisionShapes(recursive: false)
guard let floorShapes = floor.collision?.shapes, let ballShapes = ball.collision?.shapes else {return}
let floorPhysicsBodyComponent = PhysicsBodyComponent(
shapes: floorShapes,
density: 700,
material: .generate(staticFriction: 0.7, dynamicFriction: 0.6, restitution: 0.88),
mode: .static
)
floor.components.set(floorPhysicsBodyComponent)
var basketballPhysicsBodyComponent = PhysicsBodyComponent(
shapes: ballShapes,
mass: 0.624,
material: .generate(staticFriction: 0.8, dynamicFriction: 0.6, restitution: 0.6),
mode: .dynamic)
basketballPhysicsBodyComponent.angularDamping = 0.05
basketballPhysicsBodyComponent.linearDamping = 0.1
ball.components.set(basketballPhysicsBodyComponent)
root.addChild(floor)
root.addChild(ball)
content.add(root)
}
.gesture(TapGesture().targetedToAnyEntity().onEnded { event in
guard let entity = event.entity as? ModelEntity else {return}
let force:Float = 0.8
entity.applyLinearImpulse([0, 5, -1] * force, relativeTo: nil)
})
}
}