spatialos / UnrealGDK

SpatialOS GDK for Unreal Plugin
https://docs.improbable.io/unreal/
MIT License
403 stars 142 forks source link

Components added in blueprints are not replicated #773

Closed Antialiased closed 5 years ago

Antialiased commented 5 years ago

Description

Spawning a blueprint that specialises an actor, with a c++ ActorComponent added to it, will fail to replicate the added component.

Expected behavior

According to the docs and discussions with the team, ActorComponents added in this way should replicate properly.

Current behavior

The ActorComponent on this blueprint will not be managed by SpatialOS and it will not be replicated to the client. This can be observed by noting that the component is not mentioned in the Inspector breakdown of the spawned actor.

Possible solution

In SpatialGDK/Public/Schema/UnrealMetadata.h:

FORCEINLINE SubobjectToOffsetMap CreateOffsetMapFromActor(AActor* Actor, const FClassInfo& Info)
{
    SubobjectToOffsetMap SubobjectNameToOffset;

    for (auto& SubobjectInfoPair : Info.SubobjectInfo)
    {
        // REMOVED
        //UObject* Subobject = Actor->GetDefaultSubobjectByName(SubobjectInfoPair.Value->SubobjectName);
        // ADDED
        UObject* Subobject = StaticFindObjectFast(UObject::StaticClass(), Actor, SubobjectInfoPair.Value->SubobjectName);
        uint32 Offset = SubobjectInfoPair.Key;

        if (Subobject != nullptr && Subobject->IsPendingKill() == false && Subobject->IsSupportedForNetworking())
        {
            SubobjectNameToOffset.Add(Subobject, Offset);
        }
    }

    return SubobjectNameToOffset;
}

Steps to reproduce

Provide an unambiguous set of steps to reproduce this bug. Include code snippets if relevant.

  1. Create a C++ Actor, MyActor, and add some default components such as a static mesh.
  2. Create a C++ ActorComponent, MyComponent
  3. Create a Blueprint specializing MyActor, call it MyBlueprint
  4. In the blueprint, drag in MyComponent
  5. In GameState or elsewhere, use code similar to the following to spawn MyBlueprint:
    UBlueprint* MyBlueprint = LoadObject<UBlueprint>(nullptr, TEXT("Blueprint'/Game/MyBlueprint.MyBlueprint'"));
    MyActor* spawnedActor = GetWorld()->SpawnActor<MyActor>(MyBlueprint->GeneratedClass, position, rotation);
  6. Generate schema, snapshot and run Spatial
  7. Connect clients and note warnings similar to the following:

    [improbable.bridge.logging.EngineLogMessageHandler] [Worker: UnrealWorker5F6F8A35461C4C67A6C5A994E7B46699] Tried to generate initial replication state for an invalid sub-object (class SimpleBlockComponent, sub-object SimpleBlock, actor SimpleBlock_C_96). Object may have been deleted or is PendingKill. -[WorkerLogger:Unreal]

  8. In the inspector, note that the spawned objects do not have MyComponent.
girayozil commented 5 years ago

Thanks for the report. UNR-1181 tracking on our side.

girayozil commented 5 years ago

Fixed in https://github.com/spatialos/UnrealGDK/pull/809