Search Unity

Question XR Sockets with Network Transform

Discussion in 'Multiplayer' started by kenton_j, Mar 21, 2024.

  1. kenton_j

    kenton_j

    Joined:
    Sep 19, 2023
    Posts:
    5
    I am working on a Nursing Simulator using Unity 2022.3.15f1. Me and my team are relatively new to Unity and very much new to Networking. Over the last couple of weeks we have figured out how to set it up and get multiplayer to work on our project! Right now I am trying to get simple objects such as a blood pressure cuff, oximeter, etc. to attach to sockets. When testing by yourself everything works great, but when testing with multiple people everything works and is tracked well until the object is placed on the socket. It gets attached and then once one of the user picks it up it stays on the socket for the other user. The object is then unsynchronized until both users take it off of the socket and then the position begins to re-sync. I've been scowering the internet for hours and have no idea on how I might fix this.
    Important to know:
    • The Blood Pressure Cuff has the Network object script along with the Network Transform Client script
    • The socket also has those attachments and is a network object
    • The socket is attached to a character which lays idley and is not a network object
    • No other scripts are acting on either of those objects that have anything to do with the network or their positions
    Any ideas or help would be very much appreciated!!!
     
  2. CodeSmile

    CodeSmile

    Joined:
    Apr 10, 2014
    Posts:
    6,012
    We can't debug your code without seeing your code. ;)
     
    bugfinders likes this.
  3. qpegs

    qpegs

    Joined:
    Sep 25, 2021
    Posts:
    6
    I haven't tried coding network shared grabbable objects and sockets since I migrated from photon, but when I had them there I had to change ownership of the grabbable on grab for it to update. It's also important to make sure you have something similar to a ("isNetworkGrabbaed") bool, through testing I found that both me and another player could grab the same item at the same time
     
  4. kenton_j

    kenton_j

    Joined:
    Sep 19, 2023
    Posts:
    5
    We already have the ownership changing on grab :/ because two users can interchangably grab and throw objects and itt tracks over the network very well. Does a socket somehow override the Client Network Transform script the t Unity Netcode provides?
     
  5. qpegs

    qpegs

    Joined:
    Sep 25, 2021
    Posts:
    6
    It shouldn't override anything to my knowledge, but the fact that it screws up at the socket would suggest that's your problem. Perhaps do some kind of forced detach over the network when someone takes it out of the socket?

    At some point in the near future I'll be adding similar grabbable objects, when I get round to it I'll see if I run into similar issues and hopefully try fix it.
     
  6. kenton_j

    kenton_j

    Joined:
    Sep 19, 2023
    Posts:
    5
    Update:
    Our team is continuing to try to get sockets to work over the Network using the built in XR Socket, once we have a solution to that I will update this thread. In the meantime I re-wrote just basic functionality of the socket with TriggerEnter events that would run both for the client and the host at the same time which bypasses the need for RPC's. Is most definitely a work around and temporary solution, but if this helps anyone else that's great!


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Netcode;
    5.  
    6. public class NetworkSocket : NetworkBehaviour
    7. {
    8.     [SerializeField]
    9.     private GameObject objToSocket;
    10.     [SerializeField]
    11.     private GameObject attach;
    12.     private bool followSocketPos;
    13.  
    14.     private void Start()
    15.     {
    16.         followSocketPos = false;
    17.     }
    18.  
    19.     private void Update()
    20.     {
    21.         if (followSocketPos)
    22.         {
    23.             Debug.Log("Distance: "+Vector3.Distance(transform.position, objToSocket.transform.position));
    24.             if(Vector3.Distance(transform.position, objToSocket.transform.position) > .75f)
    25.             {
    26.                 followSocketPos = false;
    27.                 Physics.IgnoreCollision(GetComponent<Collider>(), objToSocket.GetComponent<Collider>(), false);
    28.             }
    29.             else
    30.             {
    31.                 objToSocket.transform.position = transform.position + attach.transform.localPosition;
    32.                 objToSocket.transform.rotation = transform.rotation * attach.transform.localRotation;
    33.             }
    34.  
    35.         }
    36.     }
    37.  
    38.     private void OnTriggerEnter(Collider other)
    39.     {
    40.         if (other.gameObject == objToSocket)
    41.         {
    42.             followSocketPos = true;
    43.             // Disable collision between the object with this script and objToSocket
    44.             Physics.IgnoreCollision(GetComponent<Collider>(), objToSocket.GetComponent<Collider>(), true);
    45.         }
    46.     }
    47.  
    48.  
    49. }
     
  7. kenton_j

    kenton_j

    Joined:
    Sep 19, 2023
    Posts:
    5
    Update:
    I had to adapt the script to reduce collisions using rigidbodies once they were attached to a socket and to allow for multiple objects to be able to enter the socket instead of just one, so I made these adjustments to the code, it also assures that only rigidbody disactivations and other changes only happen to one object at a time.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Netcode;
    5.  
    6. public class NetworkSocket : NetworkBehaviour
    7. {
    8.     [SerializeField]
    9.     private GameObject[] objsToSocket;
    10.     [SerializeField]
    11.     private GameObject attach;
    12.     private bool followSocketPos;
    13.     private Rigidbody objRb;
    14.     private GameObject currentObj;
    15.     private bool allowSocket;
    16.  
    17.     private void Start()
    18.     {
    19.         followSocketPos = false;
    20.         allowSocket = true;
    21.     }
    22.  
    23.     private void Update()
    24.     {
    25.         if (followSocketPos)
    26.         {
    27.             if(Vector3.Distance(transform.position, currentObj.transform.position) > 0.75f)
    28.             {
    29.                 followSocketPos = false;
    30.                 allowSocket = true;
    31.  
    32.                 Physics.IgnoreCollision(GetComponent<Collider>(), currentObj.GetComponent<Collider>(), false);
    33.  
    34.                 // Turns on the Rigidbodies
    35.                 if(objRb != null)
    36.                 {
    37.                     objRb.isKinematic = false;
    38.                     objRb.useGravity = true;
    39.                 }
    40.             }
    41.             else
    42.             {
    43.                 currentObj.transform.position = transform.position + attach.transform.localPosition;
    44.                 currentObj.transform.rotation = transform.rotation * attach.transform.localRotation;
    45.             }
    46.  
    47.         }
    48.     }
    49.  
    50.     private void OnTriggerEnter(Collider other)
    51.     {
    52.         foreach (GameObject objToSocket in objsToSocket)
    53.         {
    54.             if (other.gameObject == objToSocket && allowSocket)
    55.             {
    56.                 currentObj = objToSocket;
    57.                 try
    58.                 {
    59.                     objRb = currentObj.GetComponent<Rigidbody>();
    60.                 }
    61.                 catch
    62.                 {
    63.                     Debug.Log("No Rigidbody was found here");
    64.                 }
    65.  
    66.                 followSocketPos = true;
    67.                 allowSocket = false;
    68.  
    69.                 // Disable collision between the object with this script and objsToSocket
    70.                 Physics.IgnoreCollision(GetComponent<Collider>(), currentObj.GetComponent<Collider>(), true);
    71.  
    72.                 // Turns off the Rigidbodies
    73.                 if (objRb != null)
    74.                 {
    75.                     objRb.isKinematic = true;
    76.                     objRb.useGravity = false;
    77.                 }
    78.             }
    79.         }
    80.     }
    81. }