Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Question XRI & Netcode Client Grab

Discussion in 'XR Interaction Toolkit and Input' started by KKCarrot, Sep 15, 2023.

  1. KKCarrot

    KKCarrot

    Joined:
    Feb 28, 2023
    Posts:
    6
    I spawn a Network Object Interactable from server,the host grab it correctly,but the client try grabbing is warning "Only the server can reparent NetworkObjects". how can I grab On Client Side?

    Thanks!
     
    Last edited: Sep 17, 2023
  2. KKCarrot

    KKCarrot

    Joined:
    Feb 28, 2023
    Posts:
    6
    I didn‘t spawn XRrig or hand controller,these components are totally local. May this be the cause of the problem?
     
  3. Joegre

    Joegre

    Unity Technologies

    Joined:
    Aug 23, 2023
    Posts:
    14
    Two straightforward solutions:
    1) The NetworkObject component has a few checkboxes you can play around with. You might want to try unchecking "Auto Object Parent Sync" (*see attached image*) and see if it fixes it for you.

    OR

    2) You could make sure the GameObject containing the NetworkObject component does not have a parent.

    Either of these choices will prevent that error from appearing.

    That being said, this will only allow the client to pickup the object and move it around locally. Replicating the Interactable component functionality across all clients will require additional steps.

    Hope that helps!

    -Joegre
     

    Attached Files:

    Last edited: Sep 21, 2023
  4. Harald_Heide

    Harald_Heide

    Joined:
    Jul 22, 2015
    Posts:
    81
    Would be very nice with a simple example showing a cube able to be grabbed by a network client and getting synced in movement, even animation, in all the other clients view. Strange that it is so hard to find an example. Of this simple behaviour...
     
    LydiaYounsi likes this.
  5. umarautarhanov

    umarautarhanov

    Joined:
    Aug 23, 2023
    Posts:
    4
    Hi! I have done via onwership change on Grab. The script is attached to a network interactable object. However, I personally have one problem. The grab attach position is kinda twisted with a network object. But works flawlessly with a local object. Trying to figure out the problem


    using UnityEngine;
    using Unity.Netcode;
    using UnityEngine.XR.Interaction.Toolkit;

    public class NetworkGrabbableObject : NetworkBehaviour
    {
    private XRGrabInteractable grabInteractable;
    ulong clientID;
    private NetworkObject networkObject;



    public override void OnNetworkSpawn()
    {
    base.OnNetworkSpawn();

    grabInteractable = GetComponent<XRGrabInteractable>();
    networkObject= GetComponent<NetworkObject>();
    clientID= NetworkManager.Singleton.LocalClientId;


    if (grabInteractable != null)
    {
    grabInteractable.selectEntered.AddListener(OnGrabbed);

    }
    }

    private void OnGrabbed(SelectEnterEventArgs args)
    {
    RequestOwnershipServerRpc(clientID);
    }

    [ServerRpc(RequireOwnership = false)]
    private void RequestOwnershipServerRpc(ulong clientID)
    {
    networkObject.ChangeOwnership(clientID);
    }
    }
    [/code]
     
    BlocCole and KevinMartellotti like this.
  6. UnityMersus

    UnityMersus

    Joined:
    Jun 27, 2017
    Posts:
    3
    How about using Oculus SDK (hands) instead XR.Interaction.Toolkit?
     
  7. Joegre

    Joegre

    Unity Technologies

    Joined:
    Aug 23, 2023
    Posts:
    14
    Our VR Multiplayer Template will be releasing later and will have examples on how to sync this. This template will setup all of Unity's multiplayer services for you, including lobbies and spatialized voice chat, It even supports hand tracking replication, all over OpenXR!
     
  8. glowkeeper

    glowkeeper

    Joined:
    May 21, 2020
    Posts:
    6
    I also have issues reflecting an object's position across Netcode-connected clients after it's been grabbed via XRGrabInteractable. I can move them easily, otherwise, but once the XRRig gets involved, an object's network position behaves weirdly - sort of floats around - forgive me, I've tried soooooo many things (including just about every option available in the NetworkObect and XRGrabInteractable, and various different things in code), so it's hard to recreate here. However, here's the current iteration of my code:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using Unity.Netcode;
    6. using UnityEngine.XR.Interaction.Toolkit;
    7.  
    8. public class NetworkItem : NetworkBehaviour
    9. {      
    10.     private XRGrabInteractable m_GrabInteractable;
    11.  
    12.     private Rigidbody m_RigidBody;
    13.     private NetworkObject m_NetObject;
    14.  
    15.     private Vector3 m_Position;
    16.     private Quaternion m_Rotation;
    17.     private Vector3 m_Scale;
    18.     private Vector3 m_Velocity;
    19.  
    20.     private bool m_NeedsMoving = false;
    21.  
    22.     private ulong m_ClientID;
    23.  
    24.     //private const double m_IdleTime = 1000; //milliseconds
    25.     //private double m_TimeMove = 0;
    26.  
    27.     public override void OnNetworkSpawn()
    28.     {
    29.         m_ClientID = NetworkManager.Singleton.LocalClientId;
    30.         m_NetObject = gameObject.GetComponent<NetworkObject>();      
    31.         m_RigidBody = gameObject.GetComponent<Rigidbody>();      
    32.         m_GrabInteractable = gameObject.GetComponent<XRGrabInteractable>();
    33.  
    34.         if (m_GrabInteractable != null)
    35.         {
    36.             //Debug.Log("Grabbing");
    37.             m_GrabInteractable.selectEntered.AddListener(OnGrabbed);          
    38.             m_GrabInteractable.selectExited.AddListener(OnLetGo);
    39.  
    40.         } else {
    41.             Debug.Log("Cannot Grab");
    42.         }  
    43.     }
    44.  
    45.     private void OnGrabbed(SelectEnterEventArgs args)
    46.     {
    47.         SendMoveToServerRpc(transform.position, transform.rotation, transform.localScale, m_RigidBody.velocity, m_ClientID);
    48.     }
    49.  
    50.     private void OnLetGo(SelectExitEventArgs args)
    51.     {
    52.         //Debug.Log("Sending info from OnLetGo");
    53.         SendMoveToServerRpc(transform.position, transform.rotation, transform.localScale, m_RigidBody.velocity, m_ClientID);
    54.     }
    55.  
    56.     void OnCollisionEnter(Collision collision)
    57.     {
    58.         //Debug.Log("Sending info from OnCollisionEnter");
    59.         SendMoveToServerRpc(transform.position, transform.rotation, transform.localScale, m_RigidBody.velocity, m_ClientID);
    60.     }
    61.  
    62.     private void GenerateMove()
    63.     {      
    64.         if( IsOwner && transform.hasChanged )
    65.         {
    66.             //Debug.Log("Sending move info from server");
    67.             SendMoveToServerRpc(transform.position, transform.rotation, transform.localScale, m_RigidBody.velocity, m_ClientID);
    68.             transform.hasChanged = false;
    69.         }      
    70.     }
    71.    
    72.     private void ClientMove()
    73.     {
    74.         if ( !IsOwner && m_NeedsMoving)
    75.         {
    76.             //m_RigidBody.velocity = m_Velocity;
    77.             //Debug.Log("Client move on client" + m_Position.ToString() + m_Rotation.ToString());
    78.             m_RigidBody.Move(m_Position, m_Rotation);
    79.             m_NeedsMoving = false;
    80.             // transform.localScale = m_Scale;
    81.         }
    82.     }
    83.  
    84.     private void FixedUpdate()
    85.     {
    86.         GenerateMove();
    87.         ClientMove();
    88.     }
    89.  
    90.    [ServerRpc(RequireOwnership = false)]
    91.    private void SendMoveToServerRpc(Vector3 position, Quaternion rotation, Vector3 scale, Vector3 velocity, ulong clientID)
    92.    {      
    93.         // var networkTime = NetworkManager.Singleton.ServerTime.TimeAsFloat;
    94.         Debug.Log("Client move from server" + position.ToString() + rotation.ToString() + scale.ToString());      
    95.         m_NetObject.ChangeOwnership(clientID);      
    96.         SendMoveToClientRpc(position, rotation, scale, velocity);
    97.    }
    98.  
    99.    [ClientRpc]
    100.    private void SendMoveToClientRpc(Vector3 position, Quaternion rotation, Vector3 scale, Vector3 velocity)
    101.    {                
    102.         m_Position = position;
    103.         m_Rotation = rotation;
    104.         m_Scale = scale;
    105.         m_Velocity = velocity;
    106.         m_NeedsMoving = true;  
    107.    }
    108. }
    109.  
    I'm sure there's something I'm misunderstanding, but I'm kinda running out of ideas/the will to live, so any help would be appreciated (including a decent set of examples).
     
  9. Joegre

    Joegre

    Unity Technologies

    Joined:
    Aug 23, 2023
    Posts:
    14
    I'd recommend using a NetworkTransform (or more ideally a ClientNetworkTransform). Let the owner move the object and let all clients just view that movement.
     
  10. glowkeeper

    glowkeeper

    Joined:
    May 21, 2020
    Posts:
    6
    I've tried both NetworkTransform and ClientNetworkTransform, and they didn't seem to work. However, it was in the midst of an admittedly scattergun approach where I was trying everything and anything, and I may have missed something. So I will try again and attempt to be a little more systematic. Meanwhile, are there any working examples of ClientNetworkTransform and XRRigs I could reference?
     
  11. Joegre

    Joegre

    Unity Technologies

    Joined:
    Aug 23, 2023
    Posts:
    14
    What does your NetworkObject component look like on the interactables you are trying to sync across the network?
    For Instance, make sure Auto Object Parent Sync is set to False.

    upload_2024-5-17_10-17-37.png