Basically, my requirement is to import a usdz
, for an example, a car. Then apply different materials for each body part. Eg: material A
to body, material B
to side mirrors, material C to wheels etc.
I could iterate through the materials in the ModelEntity's ModelComponent and assign material as below.
func updateUIView(_ uiView: ARView, context: Context) {
let entity = try! Entity.loadModel(named: "CarScene")
var material = PhysicallyBasedMaterial()
material.baseColor = PhysicallyBasedMaterial.BaseColor(tint:.red)
material.roughness = PhysicallyBasedMaterial.Roughness(floatLiteral: 0.0)
material.metallic = PhysicallyBasedMaterial.Metallic(floatLiteral: 1.0)
for i in 0...(entity.model?.materials.count ?? 1) - 1 {
entity.model?.materials[i] = material
}
let anchor = AnchorEntity(plane: .horizontal)
anchor.addChild(entity)
uiView.scene.addAnchor(carAnchor)
}
But, I don't know which material is which. If I have multiple usdz
files, I want to be able to accurately assign materials for each body part. Is that doable?
Do I need to break the usdz
model and assign identifiers before importing to my Xcode project? Any help would be really appreciated.
Use the following sample code which shows you how to modify materials at runtime:
import SwiftUI
import RealityKit
struct ARViewContainer: UIViewRepresentable {
let arView = ARView(frame: .zero)
let fiat = try! Entity.load(named: "Fiat_Uno")
func makeUIView(context: Context) -> ARView {
print(fiat)
fiat.scale /= 5
fiat.orientation = .init(angle: .pi/1.5, axis: [0,1,0])
let anchor = AnchorEntity()
anchor.addChild(fiat)
arView.scene.anchors.append(anchor)
return arView
}
func updateUIView(_ view: ARView, context: Context) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
let wheels = fiat.findEntity(named: "Rodas_Material_001_0")?
.children[0] as? ModelEntity
wheels?.model?.materials[0] = UnlitMaterial(color: .green)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.75) {
let body = fiat.findEntity(named: "Fiat_UNO_Material_001_0")?
.children[0] as? ModelEntity
body?.model?.materials[0] = UnlitMaterial(color: .blue)
}
}
}
}
struct ContentView : View {
var body: some View {
ARViewContainer().ignoresSafeArea()
}
}