sky*_*guy 1 swift arkit reality-composer
好吧,我通过https://developer.apple.com/videos/play/wwdc2019/609/提供的 RealityComposer 游戏进行筛选,并尝试找出如何让实体移动到用户点击的位置。
我可以在 .rc 场景中引用我的对象,如下所示:
struct ARViewContainer: UIViewRepresentable {
let arView = ARView(frame: .zero)
func makeUIView(context: Context) -> ARView {
// arView = ARView(frame: .zero)
// Load the "Box" scene from the "Experience" Reality File
let boxAnchor = try! Experience.loadBox()
//*Notifications
setupNotifications(anchor: boxAnchor)
//*Access vars
if boxAnchor.box1 != nil {
//print(box1.position.x)
/// Set local position
boxAnchor.box1!.position = [1.0, 0.0, 0.5]
/// Set world position
//boxAnchor.box1.setPosition([0.5, 0.2, 1.5], relativeTo: nil)
}
Run Code Online (Sandbox Code Playgroud)
我知道这涉及某种形式的 arhitest,但是,我收到以下错误:
UIView最后没有成员?
func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
//1. Get The Current Touch Location
guard let currentTouchLocation = touches.first?.location(in: self.arView),
//2. Get The Tapped Node From An SCNHitTest
let hitTestResultNode = self.arView.hitTest(currentTouchLocation, with: nil).last?.node else { return } //error here
//3. Loop Through The ChildNodes
for node in hitTestResultNode.childNodes{
//4. If The Node Has A Name Then Print It Out
if let validName = node.name{
print("Node\(validName) Is A Child Node Of \(hitTestResultNode)")
}
}
}
Run Code Online (Sandbox Code Playgroud)
我很不知道我是否正确地处理了这件事。我引用了ARKit 中 SCNNode 上的检测触摸,但这不涉及 RealityComposer。
我怎样才能做到这一点?
通过触摸进行移动的最简单方法Entity是使用 Apple 提供的内置手势;您可以在这里阅读更多相关信息:Apple 文档
要启用您选择的手势(在本例中为翻译),请首先确保将值RealityComposer设置为您希望与之交互的每个手势。partcipatestrueEntity
然后添加一个Has Collision组件,它Entity很简单:
使实体能够与也具有碰撞组件的其他实体发生碰撞的组件。
使用它,您可以安装内置手势来为您完成繁重的工作。
假设我们在 中进行了默认RealityKit示例设置Xcode,并且我们为该框选择了参与,那么用户可以使用触摸位置平移它,就像这样简单:
class ViewController: UIViewController {
@IBOutlet var arView: ARView!
override func viewDidLoad() {
super.viewDidLoad()
//1. Load The Box Anchor
let boxAnchor = try! Experience.loadBox()
//2. Check The SteelBox Has A Collision Component & Add The Desired Gesture
if let hasCollision = boxAnchor.steelBox as? HasCollision {
arView.installGestures(.translation, for: hasCollision)
}
//Add The Box To The Scene Hierachy
arView.scene.anchors.append(boxAnchor)
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想做一些繁重的工作(谁不想!),那么您可以通过创建一个全局变量来执行类似的操作,该变量将引用您选择的实体(在本例中称为 Steel Box):
//Variable To Store Our Currently Selected Entity
var currentEntity: Entity?
Run Code Online (Sandbox Code Playgroud)
然后使用touchesBegan,touchesMoved你可以这样:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
/* Get The Current Touch Location In The ARView
Perform A HitTest For The Nearest Entity
Checks That The Tapped Entity Is The Steel Box
Set It As The Current Entity
*/
guard let touchLocation = touches.first?.location(in: arView),
let tappedEntity = arView.hitTest(touchLocation, query: .nearest, mask: .default).first?.entity,
tappedEntity.name == "Steel Box" else {
return
}
currentEntity = tappedEntity
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
/* Get The Current Touch Location In The ARView
Perform A HitTest For An Existing Plane
Move The Current Entity To The New Transfortm
Set It As The Current Entity
*/
guard let touchLocation = touches.first?.location(in: arView),
let currentEntity = currentEntity else {
return
}
if let transform = arView.hitTest(touchLocation, types: .existingPlaneUsingExtent).first?.worldTransform {
currentEntity.move(to: transform, relativeTo: nil, duration: 0.1)
}
}
Run Code Online (Sandbox Code Playgroud)
希望它有助于指出正确的方向。
| 归档时间: |
|
| 查看次数: |
979 次 |
| 最近记录: |