mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
fix: #2705 NetworkClient.SpawnPrefab looks for spawn handlers before looking for registered prefabs, instead of the other way around
This commit is contained in:
parent
7d4a9c46e4
commit
eded0a2b15
@ -1078,12 +1078,13 @@ static NetworkIdentity GetExistingObject(uint netid)
|
||||
|
||||
static NetworkIdentity SpawnPrefab(SpawnMessage message)
|
||||
{
|
||||
if (GetPrefab(message.assetId, out GameObject prefab))
|
||||
{
|
||||
GameObject obj = GameObject.Instantiate(prefab, message.position, message.rotation);
|
||||
//Debug.Log($"Client spawn handler instantiating [netId{message.netId} asset ID:{message.assetId} pos:{message.position} rotation:{message.rotation}]");
|
||||
return obj.GetComponent<NetworkIdentity>();
|
||||
}
|
||||
// custom spawn handler for this prefab? (for prefab pools etc.)
|
||||
//
|
||||
// IMPORTANT: look for spawn handlers BEFORE looking for registered
|
||||
// prefabs. Unspawning also looks for unspawn handlers
|
||||
// before falling back to regular Destroy. this needs to
|
||||
// be consistent.
|
||||
// https://github.com/vis2k/Mirror/issues/2705
|
||||
if (spawnHandlers.TryGetValue(message.assetId, out SpawnHandlerDelegate handler))
|
||||
{
|
||||
GameObject obj = handler(message);
|
||||
@ -1100,6 +1101,15 @@ static NetworkIdentity SpawnPrefab(SpawnMessage message)
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
|
||||
// otherwise look in NetworkManager registered prefabs
|
||||
if (GetPrefab(message.assetId, out GameObject prefab))
|
||||
{
|
||||
GameObject obj = GameObject.Instantiate(prefab, message.position, message.rotation);
|
||||
//Debug.Log($"Client spawn handler instantiating [netId{message.netId} asset ID:{message.assetId} pos:{message.position} rotation:{message.rotation}]");
|
||||
return obj.GetComponent<NetworkIdentity>();
|
||||
}
|
||||
|
||||
Debug.LogError($"Failed to spawn server object, did you forget to add it to the NetworkManager? assetId={message.assetId} netId={message.netId}");
|
||||
return null;
|
||||
}
|
||||
@ -1348,13 +1358,13 @@ static void DestroyObject(uint netId)
|
||||
|
||||
localObject.OnStopClient();
|
||||
|
||||
// user handling
|
||||
// custom unspawn handler for this prefab? (for prefab pools etc.)
|
||||
if (InvokeUnSpawnHandler(localObject.assetId, localObject.gameObject))
|
||||
{
|
||||
// reset object after user's handler
|
||||
localObject.Reset();
|
||||
}
|
||||
// default handling
|
||||
// otherwise fall back to default Destroy
|
||||
else if (localObject.sceneId == 0)
|
||||
{
|
||||
// don't call reset before destroy so that values are still set in OnDestroy
|
||||
|
@ -148,8 +148,9 @@ public void FindOrSpawnObject_ErrorWhenPrefabInNullInDictionary()
|
||||
Assert.IsNull(networkIdentity);
|
||||
}
|
||||
|
||||
// test to prevent https://github.com/vis2k/Mirror/issues/2705
|
||||
[Test]
|
||||
public void FindOrSpawnObject_SpawnsFromPrefabIfBothPrefabAndHandlerExists()
|
||||
public void FindOrSpawnObject_SpawnsFromHandlerIfBothPrefabAndHandlerExists()
|
||||
{
|
||||
const uint netId = 1003;
|
||||
int handlerCalled = 0;
|
||||
@ -167,13 +168,11 @@ public void FindOrSpawnObject_SpawnsFromPrefabIfBothPrefabAndHandlerExists()
|
||||
return go;
|
||||
});
|
||||
|
||||
|
||||
bool success = NetworkClient.FindOrSpawnObject(msg, out NetworkIdentity networkIdentity);
|
||||
|
||||
Assert.IsTrue(success);
|
||||
Assert.IsNotNull(networkIdentity);
|
||||
Assert.That(networkIdentity.name, Is.EqualTo($"{validPrefab.name}(Clone)"));
|
||||
Assert.That(handlerCalled, Is.EqualTo(0), "Handler should not have been called");
|
||||
Assert.That(handlerCalled, Is.EqualTo(1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
Loading…
Reference in New Issue
Block a user