Hi All,
I have successfully used UNET to spawn prefabs that were added to the network spawnable prefabs in the unity editor for clients and servers. However, I need a way to spawn randomized GameObjects at runtime. Is it possible to have my server generate new GameObjects at runtime, and then spawn those onto the clients?
So far in the code below I’ve been able to override the default spawning behavior by registering a client side spawn handler. Now when a server spawn command is issued, the remote client receives it’s own spawn command. I’ve used this to spawn a cube on the host’s client and a different cube (in green) on the remote clients in the code below.
Instead of spawning a different cube in green on the remote client(s), I need someway to recreate the server’s GameObject. Is it possible to use the assetID that is passed to reach back to the server and get the GameObject somehow? Or can I access the server’s registered spawnable prefabs and recreate it on the client? Does anyone have any other ideas?
public class TestEnemyManagerServer : NetworkBehaviour
{
private bool isNextEnemySpawnEnabled = false;
private NetworkManager myNetMan;
void Start ()
{
myNetMan= GameObject.Find ("Network Manager").GetComponent<NetworkManager>();
//Server will start checking for new enemy spawn requests every 2 seconds
if (isServer) {
InvokeRepeating ("SpawnEnemies", 2f, 2f);
}
}
public void SetNextEnemySpawnEnabled()
{
if (isServer) {
Debug.Log ("Server enabled next enemy spawn");
isNextEnemySpawnEnabled = true;
}
}
void SpawnEnemies()
{
if (isServer) {
if (isNextEnemySpawnEnabled) {
Debug.Log ("Server preparing to spawn new enemy at runtime");
GameObject theCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
theCube.transform.position = new Vector3 (0, 2, 0);
theCube.AddComponent<NetworkIdentity> ();
//Generate a new unique assetId here - not currently unique
NetworkHash128 myAssetId = NetworkHash128.Parse("e2656f");
//Add to the registered spawnable prefabs for network spawning
myNetMan.spawnPrefabs.Add(theCube);
//Call the client to register the spawn handler via RPC
RpcLoadPrefab (myAssetId);
Debug.Log ("Server spawning object across clients");
NetworkServer.Spawn(theCube,myAssetId);
//Set trigger bool back to false
isNextEnemySpawnEnabled = false;
}
}
}
[ClientRpc]
void RpcLoadPrefab(NetworkHash128 assetId)
{
Debug.Log ("Server called the Client RPC to register a client-specific handler");
ClientScene.RegisterSpawnHandler(assetId, SpawnEnemyHandler, UnSpawnEnemyHandler);
}
//This is only runs on remote clients
public GameObject SpawnEnemyHandler(Vector3 position, NetworkHash128 assetId)
{
Debug.Log ("We have entered the client-specific spawn handler");
//Here we create a cube (but make it green instead) to illustrate separate functionality
//Normally we would want to recreate the same game object that the server used
GameObject otherCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
otherCube.transform.position = position;
otherCube.AddComponent<NetworkIdentity> ();
otherCube.GetComponent<MeshRenderer>().material.color = Color.green;
return otherCube;
//HELP - How can I access the server's game object from here?
//Can I do something with assetId here?
}
//This is only runs on remote clients
public void UnSpawnEnemyHandler(GameObject spawned)
{
Destroy (spawned);
}
}
I’ve looked for days and have found nothing but dead ends. I’ve seen this question asked all in multiple threads, but haven’t found any legit answers yet. Please help!