I'm working on and learning some basics of Unity 5, UNET, and networking. I made a simple 3D game where you go around and change the colors of objects. But I want to make it multiplayer now, and I am having lots of trouble figuring out how to send the changes over the network so all players can see a single player's color change.
Part of the issue is that it has been difficult to find the answer using the newer UNET networking engine. And sometimes I come across answers that are for the older way.
So the main question is, how do I network non-player GameObject property changes? Color, shape, size, etc..
Here is some code I have now - and I've had many different versions so I'll just post the current one:
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've tried a bunch more solutions, including writing a separate script on the objects whose color I want to change and including [SyncVar] and hook functions. I've also tried Debug.Log on each of the functions I'm expecting to update the objects on the clients and they are executing with the expected data.
I really don't know what else to do. I feel like it is a VERY simple thing I want to do, but I haven't come across syncing non-player GameObject's in any questions, tutorials, or other resources. Any ideas at all would be helpful, thank you.
I found my answer. And it was very difficult, as almost every single question, post, example, etc... I could find was about player objects, and not non-player objects.
So, I needed to use the
AssignClientAuthority
function. Which I had tried a couple of times, but wasn't using it correctly. Here is the functioning C# script to apply to the player:!!!Important!!! Each object that you want to affect must have a NetworkIdentity component, and it must be set to LocalPlayerAuthority
So this script is just to change a random color, but you should be able to change the actual stuff to apply this to any change in the materials or anything else you want to network with a non-player object. "Should" being the optimal word - I haven't tried with any other functionality yet.
EDIT - added more comments for learning purposes.
i make a small modification to this code and add the possibility the script if we place the player he can make the change through the raycasting.
Unity 5.3.2p3 Assign Client Authority to Non Player Objects
For anyone interested in setting this up this is my approach
Client Side OnLocalPlayer component -> Call commands to assign and remove object authority by passing through the objects NetworkInstanceId. You can add any UI to call these methods on this component
Server Side
Client Side 3. Object component ->
OnStartAuthority() - allowed to send commands to server OnStopAuthority() - not allowed to send commands to server
That's all there is to it!
For 2018:
Rather than using "Assign Object Authority",
I really recommend simply using
.SpawnWithClientAuthority
It's really very easy.
In fact it's this simple!
{In that code, note that "connectionToClient" is magically available with no effort - it means "the client" who called this command.}
On the client (the one you want to "own" the thing), just call
CmdPleaseSpawnSomething()
.I mean - that's all there is to it, thank goodness.
There's a long clear explanation here:
https://forum.unity.com/threads/assign-authority-to-local-client-gameobject.371113/#post-3592541