Unet NetworkServer.Spawn() not working

Hello, I’m try to spawn objects over the network and to make it simple I told it to spawn a cube. The cube has the two networking components Network Identity and Network Transform. I have this code to make the cube.

using UnityEngine;
using System.Collections;
using UnityEngine.Networking;

public class Network_BuilderGUI : NetworkBehaviour 
{
	public GameObject TestPart;
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () 
	{
		if(Input.GetMouseButtonDown(0))
		{
			print ("Create");
			CreatePart();
		}
	}

	//[Command]
	void CreatePart()
	{
		GameObject Te = (GameObject)Instantiate(TestPart,transform.position,transform.rotation);
		NetworkServer.Spawn(TestPart);
	}
}

Now it seems to be that the cube gets created by the client that started it, but then I get error on the other clients “Failed to spawn server object” am I missing something because seems the manual states to do it this way?

@Guardian2300

A host is a special thing here. Mainly it’s a server but it’s a local client as well.

The registering is required for the clients to be able to find the spawnable prefabs.

I’m trying to provide you a simple “shooting” example, step by step

PART 1

  1. Create a new scene and save it

  2. Create a new game object, name it NetworkManager

  3. Add two components to it: NetworkManager and NetworkManagerHUD

  4. Create a new game object called Player. This will be our player to be spawned when connected to the server.

  5. Add a NetworkIdentity component to this object. Check “Local Player Authority”.

  6. Add a NetworkTransform component as well. This will handle the transform syncing automatically.

  7. Add a child cube or something to be able to see where the player is.

  8. Create a new (c#) script and call it Player as well. Here is the commented code:

    using UnityEngine;
    

    using UnityEngine.Networking;

    public class Player : NetworkBehaviour
    {
    public float _moveSpeed = 3.0f;

    private Vector3 _velocity;
    
    public override void OnStartLocalPlayer()
    {
        base.OnStartLocalPlayer();
    
        // you can use this function to do things like create camera, audio listeners, etc.
        // so things which has to be done only for our player
    }
    
    private void Update()
    {
        // isLocalPlayer is true for the client who "owns" the player object
        // we only want input handling for our player
        if (!base.isLocalPlayer)
            return;
    
        // handle input here...
    
        _velocity = Vector3.zero;
    
        if (Input.GetKey(KeyCode.W))
            ++_velocity.z;
        if (Input.GetKey(KeyCode.S))
            --_velocity.z;
        if (Input.GetKey(KeyCode.A))
            --_velocity.x;
        if (Input.GetKey(KeyCode.D))
            ++_velocity.x;
    
        _velocity.Normalize();
    }
    
    private void FixedUpdate()
    {
        // because Local Player Authority is true, the client has to move the player
        // only the resulting transform will be sent to the server and to the other clients
        if (!base.isLocalPlayer)
            return;
    
        // if that flag is not true, we should check that the code runs only on server
        // it could be done by checking base.isServer
    
        // transforming and other authoritive stuff here...
    
        transform.position += _velocity * Time.deltaTime * _moveSpeed;
    }
    

    }

  9. After adding the newly created Player component to the Player object, create a prefab from this object (drag & drop from the Hiearchy to the Assets tab)

  10. Select the NetworkManager, expand “Spawn Info” section, and assign the previously created prefab to the Player Prefab.

  11. If it was successful (no error messages, etc), delete the Player object from the scene.

  12. Now, if you build the game, and start the standalone, a basic movement is working. One of the game has to be the host, the other is a client (ofc, create the host first)

PART 2

  1. Create a new game object, call it Bullet

  2. Add a NetworkIdentity and a NetworkTransform components to it - note the Local Player Authority is not checked this time!

  3. Add a child sphere to be able to see the bullet

  4. Create a new (c#) script, call it Bullet. Here is the code:

     using UnityEngine;
    

    using UnityEngine.Networking;

    public class Bullet : NetworkBehaviour
    {
    public float moveSpeed = 10.0f;
    public Vector3 velocity;

     private void FixedUpdate()
     {
         // we want the bullet to be updated only on the server
         if (!base.isServer)
             return;
    
         // transform bullet on the server
         transform.position += velocity * Time.deltaTime * moveSpeed;
     }
    

    }

  5. Add the newly created Bullet script to the Bullet object.

  6. Create a prefab from this object

  7. Select the NetworkManager object and in the Spawn Info section under the Registered Spawnable Prefabs, press the + icon and assign the bullet prefab to the empty space. Now, you can remove the Bullet object from the scene

  8. This registering means that your clients will be able to spawn this object. This is a must-have step.

  9. The client cannot spawn networked object itself, it can just ask the server to spawn a new one. To have shooting, we have to modify our Player class

     // Command means when the client call this function, it's "forwarded" to the server
    

    // and the code will actually run on server side
    // NOTE: the function name has to start with “Cmd”
    [Command]
    public void Cmd_Shoot()
    {
    // create server-side instance
    GameObject obj = (GameObject)Instantiate(bulletPrefab, transform.position, Quaternion.identity);
    // setup bullet component
    Bullet bullet = obj.GetComponent();
    bullet.velocity = transform.forward;
    // destroy after 2 secs
    Destroy(obj, 2.0f);
    // spawn on the clients
    NetworkServer.Spawn(obj);
    }

    private void Update()
    {
    // … same as before

     // when pressing the space button, ask the server to spawn a bullet
     if (Input.GetKeyDown(KeyCode.Space))
         Cmd_Shoot();
    

    }

  10. Select the Player prefab, and assign the Bullet prefab to the corresponding place.

  11. Build and test it. You can now move and shoot bullets. :slight_smile:

Here is the completed project. The source code looks better than here. :slight_smile:
And Here is a “tutorial” from the Unite 2014.

//[Command]
void CreatePart()
{
GameObject Te = (GameObject)Instantiate(TestPart,transform.position,transform.rotation);
// You had “TestPart” here. You need to put “Te” because its actualy the object you are instantiating
NetworkServer.Spawn(Te);
}

I can’t comment anymore so I have to make a new answer. I try doing the unet tutorials on youtube and doesn’t want to create the object of the client the same way I am having issues with the current NetworkServer.Spawn(). This only works on the host but even then I can’t tell the clients to tell server to create Object.

I’ve tried using OnStartServer() where the function CreatePart() is supposed to create the object for the server.

void CreatePart()
{
		GameObject Te =  (GameObject)Instantiate(TestPart,transform.position,transform.rotation);
		ClientScene.RegisterPrefab(Te);
		NetworkServer.Spawn(Te);
}

Gives me an error saying on the client side can’t spawn object.
I’ve tried [Server] and [Command] Attributes but doesn’t work either. I don’t understand what I’m missing because either I get errors or the object doesn’t get spawned.

Is this not a simple “you haven’t added the prefab to the spawnable objects list in Network Manager” error?

//[Command]
void CreatePart()
{
GameObject Te = (GameObject)Instantiate(TestPart,transform.position,transform.rotation);
// You had “TestPart” here. You need to put “Te” because its actualy the object you are instantiating
NetworkServer.Spawn(Te);
}