channeldorg / channeld-ue-plugin

Enables distributed simulation with Unreal Engine's dedicated servers. 为虚幻引擎专用服务器提供分布式模拟能力的开源插件.
Apache License 2.0
132 stars 38 forks source link

Multi actor component #48

Closed laughxing closed 1 year ago

indiest commented 1 year ago

Hi @laughxing, the review is almost done, except my feedback on the GetDefaultSubobjectByName. I think the validation of this function is vital for this feature, and could be important for the future development of ChanneldUE.

laughxing commented 1 year ago

@indiest I happened to have a free morning to test this. but have not find a way to reproduce the problem on channeld-ue-demos project. this is the call stack on our project using ue5.1. image in case our code doesn't match, here's the code around line 146 of ChanneldCharacterReplicator.cpp image

with the warning log

Warning: GetActorComponentByRefChecked: Cannot find component 'LandscapeHeightfieldCollisionComponent_426' of actor LandscapeStreamingProxy_D7T4VF4LBP34PHV9XOEVM5TIG_1_5_5_0

It seems that this problem is related to the World Partition feature, but I am unable to reproduce the warning on the channeld-ue-demo project

LandscapeHeightfieldCollisionComponent_426 is a component of LandscapeStreamingProxy_D7T4VF4LBP34PHV9XOEVM5TIG_1_5_5_0. but UObject::GetDefaultSubobjectByName return nullptr

UObject* UObject::GetDefaultSubobjectByName(FName ToFind)
{
    UObject* Object = nullptr;
    // If it is safe use the faster StaticFindObjectFast rather than searching all the subobjects
    if (!GIsSavingPackage && !IsGarbageCollecting())
    {
        Object = StaticFindObjectFast(UObject::StaticClass(), this, ToFind);
        if (Object && !Object->IsDefaultSubobject())
        {
            Object = nullptr;
        }
    }
        ...
}

because of Object->IsDefaultSubobject() returning false

indiest commented 1 year ago

I see.

What is the World Partition setup of your project?

Do you use it together with the spatial channels? If so, did you call GetDefaultSubobjectByName on LandscapeStreamingProxy_D7T4VF4LBP34PHV9XOEVM5TIG_1_5_5_0 in a different server?

laughxing commented 1 year ago

I'm testing on SinglechannelDataView

indiest commented 1 year ago

Reproduced the issue:

Warning: GetActorComponentByRefChecked: Cannot find component 'LandscapeHeightfieldCollisionComponent_426' of actor LandscapeStreamingProxy_D7T4VF4LBP34PHV9XOEVM5TIG_1_5_5_0

The cause of the issue is that GetDefaultSubobjectByName can only retrieve the static/default subobject of an UObject, but the collision components of the Landscape are generate dynamically.

Fixed the issue in this commit: 01f407d3f7ff0b182a41211dd7b5ab85e6f64bbc

laughxing commented 1 year ago

@indiest the unreal_common.pb.h/cpp file is using version from master, need to generate a new version with https://github.com/metaworking/channeld/pull/44 merged to make it compile

indiest commented 1 year ago

No problem. I will merge the PR in channeld and re-generate the protobuf code.