The script for the interaction tools: "PhotonXRDirectInteractor.cs"
The prefab "DesktopInputActionManager" to trigger actions according to events
The component to manage the mouse events : "CursorControls.inputactions"
The script for the interactive objects: "Grabable.cs"
Add a "DesktopInputActionManager" to the "NavigationRig" prefab:
It relies on the mouse events to trigger the interactions through the "CursorControls.inputactions" event table
Add a 3D cursor (a small cube) to the "NavigationRig" prefab:
That will move with the "NavigationRig":
Add this object as a child of the "NavigationRig"
Set its "isTrigger" attribute to true (otherwise it will push the physical objects of the scene)
That will be seen by all the other users:
Add also a "PhotonTransformView" and a "PhotonView" to this object
That will move thanks to mouse events:
Add the "CursorDriver.cs" script (extending "MonoBehaviourPun") to this object
That will take the control over the cubes:
Add a "PhotonXRDirectInteractor.cs" script to this 3D cursor
Add a "PhotonTool.cs" script to this 3D cursor (used by the "PhotonXRDirectInteractor.cs")
Add a "XRController (Action-based)" component to this 3D cursor
Set the "Select Action" to "Cursor/Select" from the "CursorControls.inputactions" event table
Make a "Cursor" prefab of this 3D cursor
Create a grabable cube:
That will be seen by all the other users:
Add also a "PhotonTransformView" and a "PhotonView" to this object
That can be controlled by a 3D Cursor:
Add a "XR Grab Interactable" component to this cube
Try to manipulate an interactive cube with a cursor:
Make sure that the "isTrigger" property has been set to "on" for the 3D cursor
Check (and explain why) that there is a difference between:
a manipulation from the first client that has been launched
a manipulation from any other client
To obtain a better WYSIWYS situation:
Add the "Grabable.cs" Script to this same interactive cube
Add actions to call in some of the "Interactable Events" of the "XR Grab Interactable" component of the "GrabableCube"
Select Entered : Grabable.LocalCatch
Select Exited : Grabable.LocalRelease
Check that the interaction with the cube is fluid for all the clients:
Check that the PhotonView "OwnerShipTransfer" property has been set to "Takeover" for the InteractiveCube prefab
Check that this method is called in the LocalCatch method of the Grabable.cs script:
"photonView.TransferOwnership (PhotonNetwork.LocalPlayer) ;"
("photonView.RequestOwnership () ;" would be OK for "OwnerShipTransfer" property set to "Request")
Make a prefab "GrabableCube" of this grabable cube in order to instantiate easily several grabable objects
Add other actions to call in some of the "Interactable Events" of the "XR Grab Interactable" component of the "GrabableCube":
Hover Entered : Grabable.LocalShowCatchable
Hover Exited : Grabable.LocalHideCatchable
At this point the interaction awareness is provided only to the user who is interacting
Add code in the "LocalCatch" methods of "Grabable.cs" to dispatch the awareness to all the users:
photonView.RPC ("Catch", RpcTarget.Others) ; // same for "Release", "ShowCatchable", "HideCatchable"
PhotonNetwork.SendAllOutgoingCommands () ;
Do the same for "LocalRelease", "LocalShowCatchable" and "LocalHideCatchable" methods (which respectively must call "Release", "ShowCatchable" and "HideCatchable")
Check that now everybody can see the interaction awareness
Enable the user to create dynamically new instances of the "GrabableCube" prefab
Add this method in the "PhotonTool.cs" script:
public void CreateSharedObject (GameObject objectToInstanciate) {
if (photonView.IsMine) {
PhotonNetwork.Instantiate (objectToInstanciate.name, transform.position, transform.rotation, 0) ;
}
}
In the "PhotonXRDirectInteractor.cs" script:
Add 1 import:
using UnityEngine.InputSystem;
Add 2 public attributes:
public GameObject objectToInstanciate ;
public InputAction create ;
Add this code at the end of the Start method:
create.Enable () ;
create.started += ctx => CreateSharedObject () ;
Add this method :
public void CreateSharedObject () {
photonTool.CreateSharedObject (objectToInstanciate) ;
}
Then inspect the Cursor prefab In the Unity editor and:
Grab the "GrabableCube" prefab and drop it at the right place on the inspector of the "Cursor prefab" (as "Object To Instanciate")
Add a binding to the "Create" input action (click on the "+" to add a binding then double click on the "<No Binding>" field and binds to the "space" key of the keybord (by choosing the "path")
Finally, check that you can add new objects in the shared world!