Search Unity

Scene objects' transforms not updating from client to host

Discussion in 'Multiplayer' started by ZefanS, Jul 3, 2015.

  1. ZefanS

    ZefanS

    Joined:
    Jun 22, 2015
    Posts:
    18
    I have created a relatively simple scene in which players can move around and manipulate some scene objects (their transforms specifically). The players update their transforms normally, so movement of both the host and any clients is visible on all ends. However, when it comes to manipulating the scene objects, only changes made by the host are visible for the clients. Any changes made by a client are only visible to that client and not the host or the other clients.

    Here are my Network Settings:
    NetworkManager
    NetworkManager.png
    SceneObject:
    SceneObject.png
    PlayerPrefab:
    Player.png

    I looked around and found some info that suggested enabling Multiple Client Mode might fix the problem, but for some reason when I do this, it gets disabled again once I go into PlayMode.
     
  2. ZefanS

    ZefanS

    Joined:
    Jun 22, 2015
    Posts:
    18
    Does anyone know if it's possible to set Multiple Client Mode programmatically? I couldn't find anything in the API, but it seems weird to me that you wouldn't be able to set it from a script.
     
  3. ZefanS

    ZefanS

    Joined:
    Jun 22, 2015
    Posts:
    18
    So it would seem that what I want to do is actually impossible in the current version.

    From the Unity 5.2 beta release notes:
    "Previously only player objects could have local authority, which meant that the NetworkTransform (and other components) could only be used for controlling the single player object for a connection on a client. With these changes it is possible to have multiple objects on a client that are locally controlled."

    Looks like I'll be upgrading then...
     
  4. ZefanS

    ZefanS

    Joined:
    Jun 22, 2015
    Posts:
    18
    Maybe I didn't try hard enough, but the stuff from 5.2 got me nowhere.

    I've been trying to implement a message-based approach based on this thread:
    http://forum.unity3d.com/threads/iv...t-more-streamlined-flowchart-included.338228/

    My aim is to have the clients tell the server when they want to rotate the object, and then have the server actually apply the rotation, thus having the object update across the network. However, the message seems to only ever work correctly when sent from the host, not the client.

    Here's my code that handles the messages:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Networking;
    3. using UnityEngine.Networking.NetworkSystem;
    4. using System.Collections;
    5.  
    6. public class RotationHandler : NetworkBehaviour
    7. {
    8.     const short ROT_MSG = MsgType.Highest + 1;
    9.     NetworkClient client;
    10.  
    11.     public GameObject datum;
    12.  
    13.     // Use this for initialization
    14.     void Start ()
    15.     {
    16.         NetworkManager netManager = GameObject.FindObjectOfType<NetworkManager>();
    17.         client = netManager.client;
    18.         if (client.isConnected)
    19.         {
    20.             //client.RegisterHandler(ROT_MSG, ClientReceiveRotMessage);
    21.         }
    22.         if (isServer)
    23.         {
    24.             NetworkServer.RegisterHandler(ROT_MSG, ServerReceiveRotMessage);
    25.         }
    26.     }
    27.  
    28.     // Update is called once per frame
    29.     void Update ()
    30.     {}
    31.  
    32.     public void SendRotMessage(int rot)
    33.     {
    34.         IntegerMessage rotMsg = new IntegerMessage(rot);
    35.         if (client.isConnected)
    36.         {
    37.             client.Send(ROT_MSG,rotMsg);
    38.         }
    39.     }
    40.  
    41.     public void ServerReceiveRotMessage(NetworkMessage netMsg)
    42.     {
    43.         int dir = netMsg.ReadMessage<IntegerMessage>().value;
    44.         if (isServer)
    45.         {
    46.             if (datum != null)
    47.             {
    48.                 if (dir == 1)
    49.                 {
    50.                     Debug.Log("1 for Up");
    51.                     datum.GetComponent<ApplyRotation>().RotateUp();
    52.                 }
    53.                 else if (dir == 2)
    54.                 {
    55.                     Debug.Log("2 for Down");
    56.                     datum.GetComponent<ApplyRotation>().RotateDown();
    57.                 }
    58.                 else if (dir == 3)
    59.                 {
    60.                     Debug.Log("3 for Right");
    61.                     datum.GetComponent<ApplyRotation>().RotateRight();
    62.                 }
    63.                 else if (dir == 4)
    64.                 {
    65.                     Debug.Log("4 for Left");
    66.                     datum.GetComponent<ApplyRotation>().RotateLeft();
    67.                 }
    68.             }
    69.             else
    70.             {
    71.                 Debug.Log("Datum is NULL");
    72.             }
    73.         }
    74.     }
    75. }
    76.  
    Note: datum is the object being rotated. It is set explicitly by the same script that calls SendRotMessage()

    This script is attached to the Player prefab. It works as expected for the host, but nothing happens for the clients.
     
  5. emulo2

    emulo2

    Joined:
    Apr 15, 2015
    Posts:
    21
    I have the same problem. Any solutions?