如果在苹果vision pro开发时,想要实现拖拽和旋转模型时,可以用以下方法实现
import SwiftUI import RealityKit import RealityKitContent struct DeviceAnimationView: View { var viewModel: AppStateModel static let markersQuery = EntityQuery(where: .has(PointComponent.self)) static let runtimeQuery = EntityQuery(where: .has(PointOfInterestRuntimeComponent.self)) @State private var subscriptions = [EventSubscription]() @State private var attachmentsProvider = AttachmentsProvider() @State internal var rotatedEntity: Entity? = nil @State internal var rotationParent: Entity? = nil @State private var lastRotation: Rotation3D = .identity @State private var lastScale: CGFloat = 1.0 @State private var lastTransform: SIMD3<Float> = [0,0,0] @State private var isPinching = false @State private var startPinchAll = false @GestureState private var magnifyBy:CGFloat = 1.0 var body: some View { RealityView { content in do { if let entity = try?await Entity(named: "Scene",in: realityKitContentBundle){ viewModel.rootEntity = entity entity.scale=SIMD3<Float>(repeating: 1.8) entity.position=SIMD3(x:0,y:0,z:-1) content.add(entity) // subscriptions.append(content.subscribe(to: ComponentEvents.DidAdd.self, componentType: PointComponent.self, { event in // createLearnMoreView(for: event.entity) // })) viewModel.rootEntity!.children.forEach { entity in entity.components.set(InputTargetComponent(allowedInputTypes: .direct)); //entity.components.set(HoverEffectComponent()); entity.generateCollisionShapes(recursive: true) } } } .simultaneousGesture( // 拖拽 DragGesture(minimumDistance: 0.0, coordinateSpace: .local) .targetedToAnyEntity() .handActivationBehavior(.pinch) .onChanged { gestureValue in var target = gestureValue.entity //print(target.parent!.name) let newTarget = target if isPinching { if let entity = viewModel.rootEntity { startPinchAll = true while (!target.name.hasPrefix("Root") && target.parent != nil ) { target = target.parent! } let convertedTranslation = gestureValue.convert(gestureValue.translation3D, from: .local, to: target.parent!) target.transform.translation = lastTransform + limitTranslation(convertedTranslation) } } else { while (!target.name.hasPrefix("sigenstor_") && target.parent != nil ) { target = target.parent! } if target.name.hasPrefix("sigenstor_") { if target.sourceTransform == nil { target.sourceTransform = target.transform } let translation = gestureValue.translation3D let convertedTranslation = gestureValue.convert(translation, from: .local, to: target.parent!) target.transform.translation = target.sourceTransform!.translation + convertedTranslation } } } .onEnded{ gestureValue in var target = gestureValue.entity if startPinchAll { startPinchAll = false while (!target.name.hasPrefix("Root") && target.parent != nil ) { target = target.parent! } if target.name.hasPrefix("Root") { let convertedTranslation = gestureValue.convert(gestureValue.translation3D, from: .local, to: target.parent!) print(target.transform.translation) lastTransform = target.transform.translation } } else { while (!target.name.hasPrefix("sigenstor_") && target.parent != nil ) { target = target.parent! } if target.name.hasPrefix("sigenstor_") { target.sourceTransform = nil } } } ) .simultaneousGesture( // 旋转 SimultaneousGesture( RotateGesture3D(constrainedToAxis: .y, minimumAngleDelta: Angle(degrees: 10)) .targetedToAnyEntity() .onChanged { value in if let entity = viewModel.rootEntity { entity.orientation = value.convert( value.rotation * lastRotation, from: .local, to: entity.parent!) } } .onEnded { value in lastRotation *= value.rotation }, MagnifyGesture() .targetedToAnyEntity() .updating($magnifyBy){ value, gestureState, transaction in let newScale = getCuttentScale(magnification:value.magnification) viewModel.rootEntity?.setScale(SIMD3<Float>(repeating: Float(newScale)), relativeTo: nil) } .onChanged { value in isPinching = true } .onEnded { value in isPinching=false let scale = value.magnification lastScale = getCuttentScale(magnification:scale) } ) ) // .onReceive(NotificationCenter.default.publisher(for: .showAnimationNotification)) { _ in // // 显示 // viewModel.rootEntity?.isEnabled = true // }.onReceive(NotificationCenter.default.publisher(for: .hideAnimationNotification)) { _ in // // 隐藏 // viewModel.rootEntity?.anchor?.removeFromParent() // } } func limitTranslation(_ translation: SIMD3<Float>) -> SIMD3<Float> { // 设置拖动手势的范围限制条件 let maxX: Float = 100 let minX: Float = -100 let maxY: Float = 100 let minY: Float = -100 let maxZ: Float = 100 let minZ: Float = -100 // 处理拖动手势的范围限制 var limitedTranslation = translation limitedTranslation.x = min(max(limitedTranslation.x, minX), maxX) limitedTranslation.y = min(max(limitedTranslation.y, minY), maxY) limitedTranslation.z = min(max(limitedTranslation.z, minZ), maxZ) return limitedTranslation } func getCuttentScale(magnification:CGFloat)->CGFloat { let minScale: CGFloat = 0.3 let maxScale: CGFloat = 5.0 var current = lastScale*magnification current = max(min(current,maxScale),minScale) return current }
}
#Preview {
DeviceAnimationView(viewModel: AppStateModel())
.environment(AppStateModel())
}
标签:target,parent,pro,value,entity,let,var,拖拽,vision From: https://www.cnblogs.com/wxcbg/p/18641731