我正在RealityKit中创建一个应用程序,它根据用户输入生成形状.例如,如果用户输入的半径为0.1米,形状(在我的例子中为球体)的半径将为0.1米,0.2、0.3等的逻辑相同.代码都可以工作,但我想让它在用户点击屏幕时显示球体.
以下是我为接受用户输入的页面编写的代码:
class UserInput: ObservableObject {
@Published var score: Float = 0.0
}
struct PreviewView: View {
@ObservedObject var input = UserInput()
var body: some View {
NavigationView {
ZStack {
Color.black
VStack {
Text("Change the radius of your AR sphere")
.foregroundColor(.white)
Text("\(String(format: "%.1f", self.input.score)) meters")
.foregroundColor(.white)
.bold()
.font(.title)
.padding(10)
Button(action: {self.input.score += 0.1})
{
Text("Increment by 0.1 meters")
}
.padding(10)
Button(action: {self.input.score -= 0.1})
{
Text("Decrease by 0.1 meters")
}
.padding(10)
NavigationLink(destination: Reality(input: self.input)) {
Text("View in AR")
.bold()
.padding(.top,30)
}
}
}
.ignoresSafeArea()
}
}
以下是Reality ARView的代码:
struct Reality: UIViewRepresentable {
@ObservedObject var input: UserInput
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let model = ModelEntity(mesh: .generateSphere(radius: input.score))
let anchor = AnchorEntity(plane: .horizontal)
anchor.addChild(model)
arView.scene.anchors.append(anchor)
return arView
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
当用户touch 屏幕时生成形状的例子有很多,这不是我的问题.我正在接受用户输入的事实使这一点变得困难.
以下是一些代码,它们可以执行我想要的操作,但不需要用户输入.它有一些内置的物理特性,我计划在用户输入开始工作后实现这些特性.
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let planeAnchorEntity = AnchorEntity(plane: .horizontal)
let plane = ModelEntity(mesh: MeshResource.generatePlane(width: 1, depth: 1), materials: [SimpleMaterial(color: .white, isMetallic: true)])
plane.physicsBody = PhysicsBodyComponent(massProperties: .init(mass: 1), material: .generate(friction: 1, restitution: 1), mode: .kinematic)
plane.generateCollisionShapes(recursive: true)
planeAnchorEntity.addChild(plane)
arView.scene.anchors.append(planeAnchorEntity)
arView.installGestures([.scale,.rotation], for: plane)
arView.addGestureRecognizer(UITapGestureRecognizer(target: context.coordinator, action: #selector(Coordinator.handleTap)))
context.coordinator.view = arView
return arView
}
func makeCoordinator() -> Coordinator {
Coordinator()
}
func updateUIView(_ uiView: ARView, context: Context) {}
}
下面是生成我想要在大小上可调的框的协调器类:
class Coordinator {
weak var view: ARView?
@objc func handleTap(_ recognizer: UITapGestureRecognizer) {
guard let view = view else { return }
let location = recognizer.location(in: view)
let results = view.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
let anchorEntity = AnchorEntity(raycastResult: result)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3),materials: [SimpleMaterial(color: .black, isMetallic: true)])
box.physicsBody = PhysicsBodyComponent(massProperties: .init(mass: 0.5), material: .generate(), mode: .dynamic)
box.generateCollisionShapes(recursive: true)
box.position = simd_make_float3(0,0.7,0)
//static means body cannot be moved
//dynamic means it can move
//kinematic means user moved the object
anchorEntity.addChild(box)
view.scene.anchors.append(anchorEntity)
}
}
}
我试着将这两个项目融合成我想要的,但我得到了各种各样的错误,我不知道如何修复,当我try 新的东西时,出现了一堆其他错误.我认为这可以归结为@ObservedObject,以及我有多个类/ struct 将我的项目与用户输入进行比较的事实.用户输入将进入协调器类,但最终是ARViewContainer实际呈现视图.
如果有人能帮我,我将不胜感激.