Как сказано в @SilentK, для отслеживания нескольких ARImageAnchors
необходимо установить максимальное количество отслеживаемых изображений, например:
configuration.maximumNumberOfTrackedImages = 10
Который с IOS12
доступен как для ARWorldTrackingConfiguration
, так и для ARImageTrackingConfiguration
.
Поскольку вы также знаете, что когда вы добавляете ARReferenceImage
к вашему Assets Bundle
, вы должны присвоить ему name
например:
Теперь, поскольку каждая цель содержит уникальное имя, вы можете легко использовать это для загрузки различных видео. Поэтому наиболее целесообразно называть каждое видео тем же, что и ваше imageTarget.
Пример того, что вы пытаетесь сделать, может выглядеть так:
//-------------------------
//MARK: - ARSCNViewDelegate
//-------------------------
extension ViewController: ARSCNViewDelegate{
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. Check We Have Detected An ARImageAnchor
guard let validAnchor = anchor as? ARImageAnchor else { return }
//2. Create A Video Player Node For Each Detected Target
node.addChildNode(createdVideoPlayerNodeFor(validAnchor.referenceImage))
}
/// Creates An SCNNode With An AVPlayer Rendered Onto An SCNPlane
///
/// - Parameter target: ARReferenceImage
/// - Returns: SCNNode
func createdVideoPlayerNodeFor(_ target: ARReferenceImage) -> SCNNode{
//1. Create An SCNNode To Hold Our VideoPlayer
let videoPlayerNode = SCNNode()
//2. Create An SCNPlane & An AVPlayer
let videoPlayerGeometry = SCNPlane(width: target.physicalSize.width, height: target.physicalSize.height)
var videoPlayer = AVPlayer()
//3. If We Have A Valid Name & A Valid Video URL The Instanciate The AVPlayer
if let targetName = target.name,
let validURL = Bundle.main.url(forResource: targetName, withExtension: "mp4", subdirectory: "/art.scnassets") {
videoPlayer = AVPlayer(url: validURL)
videoPlayer.play()
}
//4. Assign The AVPlayer & The Geometry To The Video Player
videoPlayerGeometry.firstMaterial?.diffuse.contents = videoPlayer
videoPlayerNode.geometry = videoPlayerGeometry
//5. Rotate It
videoPlayerNode.eulerAngles.x = -.pi / 2
return videoPlayerNode
}
}
Воспроизведение с бесконечным циклом при использовании этого метода довольно сильно загружает процессор, если у вас есть несколько визуализированных экземпляров:
NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in
player.seek(to: CMTime.zero)
player.play()
}
Таким образом, вы, вероятно, захотите добавить логику, чтобы проигрывать только одно видео за раз, например выполнение SCNHitTest для VideoNode, что приведет к его воспроизведению и т. д.
Надеюсь, это поможет ...