there was simple 6 sided dice before this 12 sided dice as ModelEntity but back then it was working properly for 6 sided dice.enter image description here
let floor = ModelEntity(mesh: .generatePlane(width: 50, depth: 50), materials: [OcclusionMaterial()])
floor.generateCollisionShapes(recursive: false)
floor.components[PhysicsBodyComponent.self] = .init(
massProperties: .default,
mode: .static
)
content.add(floor)
if let diceModel = try? await Entity(named: "d20"),
let dice = diceModel.children.first?.children.first {
dice.scale = [0.1, 0.1, 0.1]
dice.position.y = 0.5
dice.position.z = -1
dice.generateCollisionShapes(recursive: true)
dice.components.set(InputTargetComponent())
dice.components.set(ImageBasedLightReceiverComponent(imageBasedLight: dice))
dice.components.set(GroundingShadowComponent(castsShadow: true))
dice.components[PhysicsBodyComponent.self] = .init(PhysicsBodyComponent(
massProperties: .default,
material: .generate(staticFriction: 0.8, dynamicFriction: 0.5, restitution: 0.1),
mode: .dynamic
))
dice.components[PhysicsBodyComponent]
dice.components[PhysicsMotionComponent.self] = .init()
content.add(dice)
}
}
.gesture(dragGesture)
}
First of all, your image shows an icosahedron
that is a three-dimensional shape with 20 (not 12, as you said) flat triangular faces. In order to generate a custom Collision Shape for any 3D polyhedron
(but not for 6-sided cube, which the .generateCollisionShapes(recursive:)
default method is generally used for) you need to use .generateConvex(from:) type method.
Here's my code:
import SwiftUI
import RealityKit
struct ContentView : View {
let entity = try! Entity.load(named: "Icosahedron")
let plane = ModelEntity(mesh: .generatePlane(width: 5, depth: 5))
init() {
plane.model?.materials = [OcclusionMaterial()]
plane.generateCollisionShapes(recursive: false)
plane.physicsBody = .init()
plane.physicsBody?.mode = .static
}
var body: some View {
RealityView { rvc in
rvc.add(plane)
print(entity)
let icosahedron = entity.findEntity(named: "Object_0") as! ModelEntity
icosahedron.scale /= 2.5
icosahedron.position = [0.0, 1.0,-4.0]
icosahedron.orientation = .init(angle: -.pi/16, axis: [1, 0.4, 0])
icosahedron.model?.materials = [SimpleMaterial(color: .white, isMetallic: false)]
Task { @MainActor in
let resource = try await ShapeResource.generateConvex(from: icosahedron.model!.mesh)
icosahedron.components[CollisionComponent.self] = .init(shapes: [resource])
}
icosahedron.physicsBody = .init()
icosahedron.physicsBody?.mode = .dynamic
rvc.add(icosahedron)
plane.position.z = icosahedron.position.z
}
}
}
A visualized Collision Shape in Xcode's visionOS Debugging: