Add support for spawning multiple objects over network within a single group that is not from Prefabs
#1066
This commit is contained in:
@@ -1505,8 +1505,8 @@ void NetworkInternal::OnNetworkMessageObjectSpawn(NetworkEvent& event, NetworkCl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recreate object locally (spawn only root)
|
// Recreate object locally (spawn only root)
|
||||||
ScriptingObject* obj = nullptr;
|
|
||||||
Actor* prefabInstance = nullptr;
|
Actor* prefabInstance = nullptr;
|
||||||
|
Array<ScriptingObject*> objects;
|
||||||
if (msgData.PrefabId.IsValid())
|
if (msgData.PrefabId.IsValid())
|
||||||
{
|
{
|
||||||
const NetworkReplicatedObject* parent = ResolveObject(rootItem.ParentId);
|
const NetworkReplicatedObject* parent = ResolveObject(rootItem.ParentId);
|
||||||
@@ -1525,7 +1525,7 @@ void NetworkInternal::OnNetworkMessageObjectSpawn(NetworkEvent& event, NetworkCl
|
|||||||
{
|
{
|
||||||
if (Objects.Contains(child->GetID()))
|
if (Objects.Contains(child->GetID()))
|
||||||
{
|
{
|
||||||
obj = FindPrefabObject(child, rootItem.PrefabObjectID);
|
ScriptingObject* obj = FindPrefabObject(child, rootItem.PrefabObjectID);
|
||||||
if (Objects.Contains(obj->GetID()))
|
if (Objects.Contains(obj->GetID()))
|
||||||
{
|
{
|
||||||
// Other instance with already spawned network object
|
// Other instance with already spawned network object
|
||||||
@@ -1557,46 +1557,77 @@ void NetworkInternal::OnNetworkMessageObjectSpawn(NetworkEvent& event, NetworkCl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!obj)
|
|
||||||
obj = FindPrefabObject(prefabInstance, rootItem.PrefabObjectID);
|
// Resolve objects from prefab instance
|
||||||
if (!obj)
|
objects.Resize(msgData.ItemsCount);
|
||||||
|
for (int32 i = 0; i < msgData.ItemsCount; i++)
|
||||||
{
|
{
|
||||||
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to find object {} in prefab {}", rootItem.PrefabObjectID.ToString(), msgData.PrefabId.ToString());
|
auto& msgDataItem = msgDataItems[i];
|
||||||
Delete(prefabInstance);
|
ScriptingObject* obj = FindPrefabObject(prefabInstance, msgDataItem.PrefabObjectID);
|
||||||
return;
|
if (!obj)
|
||||||
|
{
|
||||||
|
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to find object {} in prefab {}", msgDataItem.PrefabObjectID.ToString(), msgData.PrefabId.ToString());
|
||||||
|
Delete(prefabInstance);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
objects[i] = obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (msgData.ItemsCount == 1)
|
||||||
{
|
{
|
||||||
// Spawn object
|
// Spawn object
|
||||||
if (msgData.ItemsCount != 1)
|
|
||||||
{
|
|
||||||
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Only prefab object spawning can contain more than one object (for type {})", String(rootItem.ObjectTypeName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const ScriptingTypeHandle objectType = Scripting::FindScriptingType(rootItem.ObjectTypeName);
|
const ScriptingTypeHandle objectType = Scripting::FindScriptingType(rootItem.ObjectTypeName);
|
||||||
obj = ScriptingObject::NewObject(objectType);
|
ScriptingObject* obj = ScriptingObject::NewObject(objectType);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
{
|
{
|
||||||
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to spawn object type {}", String(rootItem.ObjectTypeName));
|
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to spawn object type {}", String(rootItem.ObjectTypeName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
objects.Add(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Spawn objects
|
||||||
|
objects.Resize(msgData.ItemsCount);
|
||||||
|
for (int32 i = 0; i < msgData.ItemsCount; i++)
|
||||||
|
{
|
||||||
|
auto& msgDataItem = msgDataItems[i];
|
||||||
|
const ScriptingTypeHandle objectType = Scripting::FindScriptingType(msgDataItem.ObjectTypeName);
|
||||||
|
ScriptingObject* obj = ScriptingObject::NewObject(objectType);
|
||||||
|
if (!obj)
|
||||||
|
{
|
||||||
|
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to spawn object type {}", String(msgDataItem.ObjectTypeName));
|
||||||
|
for (ScriptingObject* e : objects)
|
||||||
|
Delete(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
objects[i] = obj;
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
// Link hierarchy of spawned objects before calling any networking code for them
|
||||||
|
if (auto sceneObject = ScriptingObject::Cast<SceneObject>(obj))
|
||||||
|
{
|
||||||
|
Actor* parent = nullptr;
|
||||||
|
for (int32 j = 0; j < i; j++)
|
||||||
|
{
|
||||||
|
if (msgDataItems[j].ObjectId == msgDataItem.ParentId)
|
||||||
|
{
|
||||||
|
parent = ScriptingObject::Cast<Actor>(objects[j]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parent)
|
||||||
|
sceneObject->SetParent(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup all newly spawned objects
|
// Setup all newly spawned objects
|
||||||
for (int32 i = 0; i < msgData.ItemsCount; i++)
|
for (int32 i = 0; i < msgData.ItemsCount; i++)
|
||||||
{
|
{
|
||||||
auto& msgDataItem = msgDataItems[i];
|
auto& msgDataItem = msgDataItems[i];
|
||||||
if (i != 0)
|
ScriptingObject* obj = objects[i];
|
||||||
{
|
|
||||||
obj = FindPrefabObject(prefabInstance, msgDataItem.PrefabObjectID);
|
|
||||||
if (!obj)
|
|
||||||
{
|
|
||||||
NETWORK_REPLICATOR_LOG(Error, "[NetworkReplicator] Failed to find object {} in prefab {}", msgDataItem.PrefabObjectID.ToString(), msgData.PrefabId.ToString());
|
|
||||||
Delete(prefabInstance);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!obj->IsRegistered())
|
if (!obj->IsRegistered())
|
||||||
obj->RegisterObject();
|
obj->RegisterObject();
|
||||||
const NetworkReplicatedObject* parent = ResolveObject(msgDataItem.ParentId);
|
const NetworkReplicatedObject* parent = ResolveObject(msgDataItem.ParentId);
|
||||||
|
|||||||
Reference in New Issue
Block a user