Mengaktifkan gerakan di RealityKit
Saya memiliki file usdz khusus (bukan membuat melalui kode, tetapi katakanlah kursi sungguhan!). Saya menyimpan ini di Entity.
Setelah saya memilikinya, ini adalah kode saya:
func updateUIView(_ uiView: ARView, context: Context) {
if let modelEntity = model.modelEntity {
print("\(model.modelName)")
let anchorEntity = AnchorEntity(plane: .horizontal)
anchorEntity.addChild(modelEntity.clone(recursive: true))
uiView.scene.addAnchor(anchorEntity)
// modelEntity.generateCollisionShapes(recursive: true)
// If we have multiple object, recursive true help to generate collision for all of them
uiView.installGestures(.rotation, for: modelEntity as! Entity & HasCollision)
uiView.debugOptions = .showPhysics
} else {
print("Unable to load modelEntity for \(model.modelName)")
}
}
Masalahnya di sini adalah bahwa "" Jenis argumen 'Entitas' tidak sesuai dengan jenis 'HasCollision' yang diharapkan ". Jadi saya tidak bisa menambahkan isyarat apapun.
Tetapi saya tidak dapat menemukan sumber daya yang berguna untuk mencapai tujuan akhir saya. Apakah ada nasihat?
Jawaban
Gunakan bentuk paksa downcasting (tipe casting) as!dengan Entity & HasCollision.
arView.installGestures([.rotation], for: modelEntity as! Entity & HasCollision)
atau begini:
let entity = modelEntity as? Entity & HasCollision
arView.installGestures([.all], for: entity!)
Sebuah sumber metode contoh installGestures(_:for:)terlihat seperti ini:
@discardableResult func installGestures(_ gestures: ARView.EntityGestures = .all,
for entity: HasCollision) -> [EntityGestureRecognizer]
Pengaturan Awal di Reality Composer
Sebelum kompilasi, di set Komposer Realitas physics = participatesdan motion type = fixeddan accessibility = accessibility enableduntuk model Anda.
Versi kode lengkap
import SwiftUI
import RealityKit
struct ARViewContainer: UIViewRepresentable {
let boxAnchor = try! Experience.loadBox()
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
arView.scene.anchors.append(boxAnchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {
if let modelEntity: Entity = boxAnchor.steelBox {
let anchorEntity = AnchorEntity(.plane(.vertical,
classification: .wall,
minimumBounds: [0.2, 0.2]))
anchorEntity.addChild(modelEntity.clone(recursive: true))
uiView.scene.addAnchor(anchorEntity)
modelEntity.generateCollisionShapes(recursive: true)
uiView.installGestures([.all],
for: modelEntity as! Entity & HasCollision)
uiView.debugOptions = [.showPhysics]
}
}
}
Masalahnya adalah Anda mencoba memberi ModelEntity kemampuan yang tidak dimilikinya (Tidak memiliki penangan tabrakan).
Anda perlu membuat Entitas sendiri, yang akan sesuai dengan HasCollision.
Saya akan mencoba sesuatu seperti ini:
import RealityKit
class MyEntity: Entity, HasAnchoring, HasModel, HasCollision {
}
func updateUIView(_ uiView: ARView, context: Context) {
// This is simply to create a dummy modelEntity
let plane = MeshResource.generatePlane(width: 0.1, depth: 0.1)
let texture = MaterialColorParameter.color(UIColor.red)
var material = SimpleMaterial()
material.baseColor = texture
let modelEntity = ModelEntity(mesh: plane, materials: [material])
// This is the class we have wrapping the model
let myEntity = MyEntity()
myEntity.addChild(modelEntity)
// Now, we add the collision component
let boxShape = ShapeResource.generateBox(width: 0.1, height: 0.1, depth: 0.1)
let boxShapeCollisionComponent = CollisionComponent (
shapes: [boxShape],
mode: .trigger,
filter: .default
)
myEntity.collision = boxShapeCollisionComponent
// Or, you could of called myEntity.generateCollisionShapes(recursive: true)
// Last thing, lets put this plane, with a box collision component,
// right in front of us
myEntity.transform = Transform.identity
myEntity.transform.translation.z = myEntity.transform.translation.z - 0.3
uiView.scene.addAnchor(myEntity)
uiView.installGestures(.rotation, for: myEntity)
uiView.debugOptions = .showPhysics
}
Saya mendapat beberapa situasi lain: Saya perlu memuat model dari .usdzfile dan itu harus memiliki animasi. Tetapi saya juga perlu memiliki gerakan seperti terjemahan dan rotasi. Penelitian itu mengarahkan saya ke utas dengan jawaban yang benar. Kode darinya akan saya tunjukkan di bawah, ide utamanya adalah "untuk menyarangkan entitas yang dimuat yang memiliki animasi di dalam ModelEntity, dan kemudian memberi ModelEntity itu CollisionComponent yang sesuai berdasarkan batas model yang dimuat." (c)
loadRequest = Entity.loadAsync(contentsOf: url).sink(receiveCompletion: { status in
print(status)
}) { entity in
// Scaling entity to a reasonable size
entity.setScale(SIMD3(repeating: 0.01), relativeTo: nil)
// Creating parent ModelEntity
let parentEntity = ModelEntity()
parentEntity.addChild(entity)
// Anchoring the entity and adding it to the scene
let anchor = AnchorEntity(.plane(.horizontal, classification: .any, minimumBounds: .zero))
anchor.addChild(parentEntity)
self.arView.scene.addAnchor(anchor)
// Playing availableAnimations on repeat
entity.availableAnimations.forEach { entity.playAnimation($0.repeat()) }
// Add a collision component to the parentEntity with a rough shape and appropriate offset for the model that it contains
let entityBounds = entity.visualBounds(relativeTo: parentEntity)
parentEntity.collision = CollisionComponent(shapes: [ShapeResource.generateBox(size: entityBounds.extents).offsetBy(translation: entityBounds.center)])
// installing gestures for the parentEntity
self.arView.installGestures(for: parentEntity)
}