Search Unity

[SOLVED] How to set transform.parent via RPC?

Discussion in 'Multiplayer' started by cj-currie, Oct 1, 2009.

  1. cj-currie

    cj-currie

    Joined:
    Nov 27, 2008
    Posts:
    337
    Hey, all,

    I'd really like to set the parent attribute of an object via an RPC call. Normal state synchronization of a transform property doesn't seem to be working, so I'd like to do a one-shot RPC. Unfortunately, RPC calls can't take Transforms as one of the parameters. Any suggestions?
     
  2. Factoid

    Factoid

    Joined:
    Mar 30, 2008
    Posts:
    69
    I've done this, but I'm at home right now. I'll post some snippets once I'm at the office, couple hours from now.
     
  3. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    sending the parent would be useless as it won't exist on other machines. you must use tags / names to identify parents and relink them again, not memory references.
     
  4. cj-currie

    cj-currie

    Joined:
    Nov 27, 2008
    Posts:
    337
    That's what I'm trying to do, communicate the equivalent object over the network. Rather than parent a client object to an object on the server, I want to tell the client to parent an object to the equivalent object that's been Network.Instantiate(d).

    Basically, like this:
    Code (csharp):
    1. @ RPC
    2. function SetParent(id : NetworkViewID){
    3.    var view : NetworkView = networkView.Find(id);
    4.     myTrans.parent = view.GetComponent(Transform);
    5. }
    In another script:
    Code (csharp):
    1.  
    2. var customizedPart = Network.Instantiate(partPrefab, Vector3.zero,Quaternion.identity,0);
    3. customizedPart.networkView.RPC("SetParent",RPCMode.All,networkView.viewID);
    Except

    Is that clearer?it doesn't work. And really it should :p
     
  5. Factoid

    Factoid

    Joined:
    Mar 30, 2008
    Posts:
    69
    Sorry, completely forgot to post the code for this.
    Code (csharp):
    1.  
    2.     string GetMountPath()
    3.     {
    4.         string str = "";
    5.         Transform cur = transform.parent;
    6.         while( cur.parent != null )
    7.         {
    8.             str = cur.name + "/" + str;
    9.             cur = cur.parent;
    10.         }
    11.         return str.Trim( "/".ToCharArray() );
    12.     }
    13.    
    14.     [RPC]
    15.     void RPCLinkToParent( string mountPath, NetworkViewID rootID, Vector3 lPos, Vector3 lEuler )
    16.     {
    17.         Transform rootPoint = NetworkView.Find( rootID ).transform;
    18.         //Debug.Log( "Got SyncMount for " + mountPath + " on object " + rootPoint.gameObject.name );
    19.         StartCoroutine( DoMount( mountPath, rootPoint, lPos, lEuler ) );
    20.     }
    21.    
    22.     IEnumerator DoMount( string mountPath, Transform rootPoint, Vector3 lPos, Vector3 lEuler )
    23.     {
    24.         Transform mountPoint = rootPoint.transform.Find( mountPath );
    25.         while( mountPoint == null )
    26.         {
    27.             //Debug.Log( "Mount point didn't exist yet" );
    28.             yield return new WaitForSeconds( 0.5f );
    29.             mountPoint = rootPoint.transform.Find( mountPath );
    30.         }
    31.  
    32.         //Debug.Log( "Mounting object " + gameObject.name + " to position " + lPos );
    33.         transform.parent = mountPoint;
    34.         transform.localEulerAngles = lEuler;
    35.         transform.localPosition = lPos;
    36.     }
    37.    
    38.     void SyncMount()
    39.     {
    40.         if( networkView.isMine )
    41.         {
    42.             //Debug.Log( "Sending SyncMount for " + gameObject.name, gameObject );
    43.             string mountPath = GetMountPath();
    44.             NetworkViewID vID = transform.root.networkView.viewID;
    45.             //Debug.Log( "Root path is " + mountPath + ", root ID is " + vID );
    46.             networkView.RPC( "RPCLinkToParent", RPCMode.OthersBuffered, mountPath, vID, transform.localPosition, transform.localEulerAngles );
    47.         }
    48.     }
    49.  
    In this instance, the object that I want to parent over the network has already been parented. The root of the parent object contains a network view that I'll need to find on the other system. Obviously the object that I'm parenting also has a network view, since it's making the RPC call to it's other versions of itself.

    So once you've parented the child network object to the other network object on the 'owner', you simply call SyncMount, and all the other child objects will automagically mount to their parent object.
     
  6. cj-currie

    cj-currie

    Joined:
    Nov 27, 2008
    Posts:
    337
    Thanks, factoid, I think I just didn't understand the NeworkView.Find() function well enough.
     
  7. Dancorg

    Dancorg

    Joined:
    Mar 27, 2011
    Posts:
    1
    Hi! I have some problems using that code

    1- In GetMountPath (), since the parent of the object i want to parent doesn't have any parent, I changed this line:
    Transform cur = transform.parent;
    to this
    Transform cur = transform;
    otherwise this: while( cur.parent != null ) will always be null

    2- I would like to know how should mountPath looks like because i keep getting a null in mountPoint in DoMount()

    In the game i have the players objects called 'Soul' which are parents of the objects 'piedras'
    GetMountPath returns 'piedras(Clone)'

    I know this is a very old post but it's the only one i found, if there is a better or simpler method to parent over a network i would be very happy to know it, thanks!