Mostafa
Mostafa

Reputation: 1612

RealityKit – Synchronization Component

I am trying to build a collaborative session using RealityKit. As far as I understand I need to conform to synchronisation component to my Entity.

So my question is: is there any source of documentation about using this component? Specially that I don't understand if I should handle from the recipient side any delegate methods for handing received data.

One thing that I want to stress: I am searching for solution with RealityKit not ARKit 3. And as per apple in the WWDC they say:

If you are using RealityKit, this is the only new code you need to add to use collaborative session. If you are not using RealityKit, then you need to implement additional two delegate functions to transmit the collaboration data.

Thanks.

Upvotes: 2

Views: 947

Answers (2)

Adam Cooper
Adam Cooper

Reputation: 21

For RealityKit you simply need to hook up a synchronisation service. In your viewDidLoad before you start your session, add this...

if let mcSession = mcSession {
        do {
            let syncService = try MultipeerConnectivityService(session: mcSession)
            arView.scene.synchronizationService = syncService
        } catch {
            fatalError("Couldn't attach a multipeer session to our ARView scene.")
        }
    } else {
        // Please start a multipeer session before configuring your ARView.
    }

Upvotes: 0

Andy Jazz
Andy Jazz

Reputation: 58043

Adopt ARSessionDelegate and MCSessionDelegate protocols, implement their delegates and set isCollaborationEnabled instance property to true:

import RealityKit
import ARKit
import MultipeerConnectivity

class ViewController: UIViewController, ARSessionDelegate, MCSessionDelegate {

    @IBOutlet var arView: ARView!
    var mcSession: MCSession?

    override func viewDidLoad() {
        super.viewDidLoad()
        arView.session.delegate = self
        mcSession!.delegate = self

        let config = ARWorldTrackingConfiguration()   
        config.planeDetection = [.horizontal]
        config.isCollaborationEnabled = true

        arView.debugOptions = [.showFeaturePoints]
        arView.session.run(config)
    }
}

Then use ARSessionDelegate's and MCSessionDelegate's session() instance methods:

extension ViewController {

    let name = UIDevice.current.name
    let myPeerID = MCPeerID(displayName: name)
    var peers = [MCPeerID]()
    peers.append(myPeerID)

    func session(_ session: ARSession,
                 didOutputCollaborationData data: ARSession.CollaborationData) {

        self.mcSession = MCSession(peer: myPeerID,
                       securityIdentity: nil,
                   encryptionPreference: .required)

        do {
            try self.mcSession.send(data.collaborationData(),
                            toPeers: peers,
                               with: .reliable)
        } catch {
            print("Get Error while outputting Collaboration Data")
        }
    }

    func session(_ session: MCSession, 
           didReceive data: Data, 
           fromPeer peerID: MCPeerID) {

        self.arView.session.update(with: data.data())
    }

    func session(_ session: ARSession,
         didRemove anchors: [ARAnchor]) {

        for anchor in anchors {
            if anchor.sessionIdentifier = session.identifier {
                // your anchors here...
            } 
        }
    }
}

extension ARSession.CollaborationData {
    func collaborationData() -> Data {
        let data = Data()
        // ...
        return data
    }
}
extension Data {
    func data() -> ARSession.CollaborationData {
        let data = ARSession.CollaborationData(coder: nsCoder)
        // ...
        return data!
    }
}

You can read and watch about it here.

Upvotes: 1

Related Questions