How to synchronize Game Player properties in Unet / Unity5?

I’m studying some of the basics of Unity 5, UNET, and networking. I made a simple 3D game in which you go and change the colors of objects. But now I want to make it multi-user, and I have a lot of problems figuring out how to send changes over the network so that all players can see the color change of one player.

Part of the problem is that it was difficult to find the answer using the new UNET networking engine. And sometimes I come across answers that are for an older way.

So, the main question is how to change the properties of a GameIbject property other than a player? Color, shape, size, etc.

Here is some code that I have now - and I had many different versions, so I’ll just post the current version:

using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Player_Paint : NetworkBehaviour { private int range = 200; [SerializeField] private Transform camTransform; private RaycastHit hit; [SyncVar] private Color objectColor; [SyncVar] private GameObject objIdentity; void Update () { CheckIfPainting(); } void CheckIfPainting(){ if(Input.GetMouseButtonDown(0)) { if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) { string objName = hit.transform.name; CmdPaint(objName); } } } [ClientRpc] void RpcPaint(){ objIdentity.GetComponent<Renderer>().material.color = objectColor; } [Command] void CmdPaint(string name) { objIdentity = GameObject.Find (name); //tell us what was hit objectColor = new Color(Random.value, Random.value, Random.value, Random.value); RpcPaint (); } } 

I tried many solutions, including writing a separate script object whose color I want to change, including the [SyncVar] and hook functions. I also tried Debug.Log for each of the functions that I expect to update on the objects, and they execute with the expected data.

I really don't know what else to do. I feel that this is a VERY simple thing that I want to do, but I have not come across non-player GameObject synchronization in any questions, tutorials or other resources. Any ideas at all would be helpful, thanks.

+5
source share
3 answers

I have found my answer. And it was very difficult, since almost every question, post, example, etc. I could find information about player objects, and not about non-game objects.

So, I needed to use the AssignClientAuthority function. Which I tried a couple of times but did not use it correctly. Here's the C # script for the application to the player:

 using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Player_Paint : NetworkBehaviour { private int range = 200; [SerializeField] private Transform camTransform; private RaycastHit hit; [SyncVar] private Color objectColor; [SyncVar] private GameObject objectID; private NetworkIdentity objNetId; void Update () { // only do something if it is the local player doing it // so if player 1 does something, it will only be done on player 1 computer // but the networking scripts will make sure everyone else sees it if (isLocalPlayer) { CheckIfPainting (); } } void CheckIfPainting(){ // yes, isLocalPlayer is redundant here, because that is already checked before this function is called // if it the local player and their mouse is down, then they are "painting" if(isLocalPlayer && Input.GetMouseButtonDown(0)) { // here is the actual "painting" code // "paint" if the Raycast hits something in it range if (Physics.Raycast (camTransform.TransformPoint (0, 0, 0.5f), camTransform.forward, out hit, range)) { objectID = GameObject.Find (hit.transform.name); // this gets the object that is hit objectColor = new Color(Random.value, Random.value, Random.value, Random.value); // I select the color here before doing anything else CmdPaint(objectID, objectColor); // carry out the "painting" command } } } [ClientRpc] void RpcPaint(GameObject obj, Color col){ obj.GetComponent<Renderer>().material.color = col; // this is the line that actually makes the change in color happen } [Command] void CmdPaint(GameObject obj, Color col) { objNetId = obj.GetComponent<NetworkIdentity> (); // get the object network ID objNetId.AssignClientAuthority (connectionToClient); // assign authority to the player who is changing the color RpcPaint (obj, col); // usse a Client RPC function to "paint" the object on all clients objNetId.RemoveClientAuthority (connectionToClient); // remove the authority from the player who changed the color } } 

!!! Important!!! Each object you want to affect must have a NetworkIdentity component and must be set to LocalPlayerAuthority

So this script is just to change the random color, but you should be able to change the actual materials to apply this to any changes in the materials or anything else that you want to connect to an object other than the player. "If" the optimal word "- I have not tried it with any other functionality yet.

EDIT - added more comments for educational purposes.

+11
source

Unity 5.3.2p3 Assigning client privileges to objects without a player

For anyone interested in tweaking this, this is my approach

Client Side OnLocalPlayer Component β†’ Call commands for assigning and removing object permissions, passing through NetworkInstanceId objects. You can add any user interface to call these methods on this component.

Server side

  [Command] void CmdAssignObjectAuthority(NetworkInstanceId netInstanceId) { // Assign authority of this objects network instance id to the client NetworkServer.objects[netInstanceId].AssignClientAuthority(connectionToClient); } [Command] void CmdRemoveObjectAuthority(NetworkInstanceId netInstanceId) { // Removes the authority of this object network instance id to the client NetworkServer.objects[netInstanceId].RemoveClientAuthority(connectionToClient); } 

Client side 3. Object component β†’
OnStartAuthority () - allowed to send commands to the server OnStopAuthority () - not allowed to send commands to the server

That’s all you need!

+2
source

I will make a slight modification to this code and add a script feature if we place a player that he can contribute to raycasting.

 using UnityEngine; using System.Collections; using UnityEngine.Networking; public class Raycasting_Object : NetworkBehaviour { private int range = 200; // [SerializeField] private Transform camTransform; private RaycastHit hit; [SyncVar] private Color objectColor; [SyncVar] private GameObject objectID; private NetworkIdentity objNetId; void Update () { if (isLocalPlayer) { CheckIfPainting (); } } void CheckIfPainting(){ Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); Debug.DrawRay (ray.origin, ray.direction * 100, Color.cyan); if(isLocalPlayer && Input.GetMouseButtonDown(0)) { if (Physics.Raycast (ray.origin, ray.direction, out hit, range)) { objectID = GameObject.Find (hit.transform.name); // this gets the object that is hit Debug.Log(hit.transform.name); objectColor = new Color(Random.value, Random.value, Random.value, Random.value); // I select the color here before doing anything else CmdPaint(objectID, objectColor); } } } [ClientRpc] void RpcPaint(GameObject obj, Color col){ obj.GetComponent<Renderer>().material.color = col; // this is the line that actually makes the change in color happen } [Command] void CmdPaint(GameObject obj, Color col) { objNetId = obj.GetComponent<NetworkIdentity> (); // get the object network ID objNetId.AssignClientAuthority (connectionToClient); // assign authority to the player who is changing the color RpcPaint (obj, col); // usse a Client RPC function to "paint" the object on all clients objNetId.RemoveClientAuthority (connectionToClient); // remove the authority from the player who changed the color } } 
0
source

Source: https://habr.com/ru/post/1234987/


All Articles