UNET object that anyone can move

So I’m making a simple block “editing” game. Each block has handles and I’m fully able to change the scale and change the position of the blocks. Now I want to add the blocks to multiplayer. I’ve gotten really close a few times but it seems to always come down to server authority.

My question is:

How do I spawn a block so everyone has authority to change the blocks transform values?

Please make a simple list with things like:

  • prefab needs to be in the network manager, registered spawnable prefabs
  • prefab needs a Network Identity
  • Network Identity needs “Local Player Authority” checked
  • when you spawn an object use this script…
  • when you edit the transform values, change them on all computers with…

I’ve tried so many variations of the script from different tutorials like bullet spawning, enemy spawning but they are always “tied to” either the player or the server. Is there not a way for an object to be independent?


This is my current script ObjectSync.cs:

`
using UnityEngine;
using UnityEngine.Networking;
public class ObjectSync : NetworkBehaviour
{
public bool beingUsed = false;

[Command]
public void CmdUpdateTransform(Vector3 _pos, Quaternion _rot, Vector3 _sca)
{
	transform.position = _pos;
	transform.rotation = _rot;
	transform.localScale = _sca;

	RpcUpdateTransform (_pos, _rot, _sca);
}

[Command]
public void CmdBeingUsed(bool _b)
{
	beingUsed = _b;

	RpcBeingUsed (_b);
}

[ClientRpc]
public void RpcUpdateTransform(Vector3 _pos, Quaternion _rot, Vector3 _sca)
{
	transform.position = _pos;
	transform.rotation = _rot;
	transform.localScale = _sca;
}

[ClientRpc]
public void RpcBeingUsed(bool _b)
{
	beingUsed = _b;
}

}`

And here is how I’m spawning the object:

[Command] void CmdSpawnObject(string go, Vector3 pos, Quaternion rot) { GameObject spawnedObject = (GameObject)Instantiate(cube, pos, rot); NetworkServer.Spawn(spawnedObject); }

The cubes are working on the server but are not spawning at all on the client

You simply can’t give everyone authority over the same object. Note that every player has it’s own environment and it’s own version of every object. If the owner change the position of the object it sends this change to the server which relays this information to all other peers. However if two or more players could send updates it’s almost impossible to tell whos position change should actually be the current position. Imagine player 1 move an object to (10,20,30) and player 2 moves it to (-45,10,100). What should actually happen? The object can only be in one position.

What you usually do in such cases is let the server own the object and use commands that the players can send over their playerobjects to request a certain change on that object

Here’s an example how this could be implemented.

  • The block objects must be spawned and owned by the server. If you want the clients to be able to spawn them, add a Command for that.
  • The script with the Commands must be on the player object/prefab, not on the block object/prefab.
  • The block GameObjects must have a NetworkIdentity component and a NetworkTransform to sync the changes to clients. Instead of a NetworkTransform, you can also use your own ClientRpc to update the transform on the clients.

This is the base of the script (attach this to the player controller object of each player, single component per player):

[SyncVar]
GameObject editingBlock;
// This is a reference to the block currently being edited by this player.
// The server may set this to the requested block through the CmdStartEditing command and it is automatically synced back to the clients.

[Command]
void CmdStartEditing(GameObject block)
{
    // The server may update editingBlock here and the SyncVar will sync it's value back to the client.
    // If any other player has the same value (excluding null), this command must fail. To check this, you can maintain a list of players or fetch the PlayerControllers using the NetworkServer.connections api.
    // If the editingBlock does not change to the requested value, the client knows that the requested block cannot be edited. You can add a ClientRpc to notify the client about failure or success.
}

[Command]
void CmdEndEditing()
{
    // The server can set editingBlock to null here.
}

[Command]
void CmdEditBlock(Vector3 position)
{
    // The server sets values of the transform on the editingBlock object. Add the parameters you need.
    // The transform is synced to the clients using a NetworkTransform or a ClientRpc.
}