Самый простой способ заставить Entity
двигаться через прикосновение - это использовать встроенные жесты, предоставляемые Apple; о которой вы можете прочитать здесь: Документация Apple
Чтобы включить ваш жест выбора (в данном случае перевод), сначала убедитесь, что в RealityComposer
установлено значение partcipates
на true
на каждом Entity
, с которым вы будете sh взаимодействовать.
Затем добавляется 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)
}
}
В качестве альтернативы, если вы Если вы захотите сделать тяжелую работу (а кто нет!), то вы можете сделать что-то вроде этого, создав глобальную переменную, которая будет ссылаться на выбранную вами сущность (которая в данном случае называется Steel Box):
//Variable To Store Our Currently Selected Entity
var currentEntity: Entity?
Затем, используя 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)
}
}
Надеюсь, это поможет направить в правильном направлении.