UNET Networking - Invalid Asset ID (a.k.a AssetID)
Hi Guys,
I am new to UNET (Unity 5.1) and I am stuck on this seemingly simple issue. I looked around the whole day so I am ready to ask for help :)
I am creating GameObjects dynamically and trying to spawn them in the network. The problem is that if I create them dynamically and add NetworkIdentity to them, the asset ID becomes 000000000000. So, I cannot spawn them in the network.
If I save them as prefab (the same GameObject), they get assigned a an asset ID in the prefab. However, I do not want to save them as prefabs as I am doing things dynamically.
How do I force a GameObject to get assigned a valid asset ID?
Thanks!
I'm not sure if you can do this, however you may want to take a look at This page in the Unity $$anonymous$$anual. There's a section titled 'Spawning $$anonymous$$anagement' and it mentions dynamically spawning and adding objects to the 'Registered Spawnable Prefabs' via the ClientScene.RegisterPrefab() function. It looks like you can pass a Gameobject to it, so it may help in your case.
Alternatively, would your system work if you had an empty gameobject with a network identity set as a spawnable prefab, then added your components after it was spawned? You would probably need to mirror the same spawning on clients to make sure everything is setup properly, but you should be able to achieve that with ClientRpc's.
Did you ever resolve this? I am having this issue as well. I'd like to create a GameObject dynamically and Spawn it.
This is what I have as a test:
GameObject test = GameObject.CreatePrimitive (PrimitiveType.Cube);
test.AddComponent<NetworkIdentity> ();
test.AddComponent<NetworkTransform> ();
ClientScene.RegisterPrefab (test);
GameObject newThing = (GameObject)Instantiate (test);
newThing.transform.position = new Vector3 (Random.Range (-4, 4), Random.Range (-4, 4), Random.Range (-4, 4));
newThing.transform.localScale = new Vector3 (Random.Range (1, 3), Random.Range (1, 3), Random.Range (1, 3));
NetworkServer.Spawn (newThing);
The objects will spawn correctly on the host, but not on the client because the asset ID is 000000000000. Yes, it works if I create the cube as a prefab and add it to the spawn prefab list, but I'd like to do it dynamically. This seems like it should work, but doesn't.
Hi, I think I was faced with a similar situation, I also can not spawn dynamically created objects, but I did not have error as you. Look at my code, may be we can together find out =)
using UnityEngine;
using UnityEngine.Networking;
public class Test : Network$$anonymous$$anager
{
// public GameObject testPrefab;
public override void OnServerAddPlayer(NetworkConnection conn, short playerCOntrollerId)
{
Debug.Log("Add new player!");
// GameObject result = (GameObject)Instantiate(testPrefab, Vector3.zero, Quaternion.identity);
// NetworkServer.AddPlayerForConnection(conn, result, playerCOntrollerId);
GameObject result = SpawnPlayerObject(Vector3.zero, NetworkHash128.Parse("asd"));
NetworkServer.AddPlayerForConnection(conn, result, playerCOntrollerId, NetworkHash128.Parse("asd"));
}
public override void OnClientConnect(NetworkConnection conn)
{
Debug.Log("New player connected!");
// ClientScene.RegisterPrefab(testPrefab);
ClientScene.RegisterSpawnHandler(NetworkHash128.Parse("asd"), SpawnPlayerObject, UnspawnPlayerObject);
base.OnClientConnect(conn);
}
public GameObject SpawnPlayerObject(Vector3 position, NetworkHash128 hash)
{
Debug.Log("Custom new player spawn!");
GameObject result = GameObject.CreatePrimitive(PrimitiveType.Capsule);
result.AddComponent<NetworkIdentity>();
result.AddComponent<NetworkTransform>();
new GameObject("player-child").transform.SetParent(result.transform);
result.transform.position = position;
return result;
}
public void UnspawnPlayerObject(GameObject unspawnObject)
{
Debug.Log("Custom player unspawn!");
Destroy(unspawnObject);
}
}
@DrSpritz Is your question in relation to getting an invalid asset id? Not sure what your error is or how it relates to the original question.
So after a little more digging, I'm wondering if the ClientScene needs some form of initialization, or if there's a bug in Unity's code.
After my ClientScene.RegisterPrefab
call, I iterated through the list of registered prefabs and printed them out:
Dictionary<NetworkHash128, GameObject> rp = ClientScene.prefabs;
foreach($$anonymous$$eyValuePair<NetworkHash128, GameObject> entry in rp) {
print(entry.Value + "\n" + entry.$$anonymous$$ey);
}
This printed out all the objects I had previously registered (through the inspector) as well as my new one, so it was being added. Only difference was that the previously registered ones all had scrambled hash values for their keys whereas my new object had 000000000000 for the key. It seems like RegisterPrefab doesn't assign a unique key for some reason.
Did you see source code of unity networking? If not, i think it will be interesting for you, in particular ClientScene.cs implementation and other
Thank you for that link. I didn't even think to look if their source code was available.