UPROPERTY required for RPC

Hey,

I’m trying to get RPC working on a UObject, and I’m aware I require the following:

    bool IsSupportedForNetworking() const override;
    virtual bool CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack) override;
    virtual int32 GetFunctionCallspace(UFunction* Function, void* Parameters, FFrame* Stack) override;

Which is fine and well, however I also appear to require a UPROPERTY

    UPROPERTY()
    bool bUnused;

If I don’t add this useless property the FFieldCache for my class wont be found, and the CallRemoteFunction will fail to call the remote function.

(screenshot: NetworkDriver.cpp)

Is there a workaround to this? Is there a way to force the creation of a field cache (or subvert the need) for my type without adding a useless property to it?

Thanks.

Also not that I think it’s relevant, but I imagine somebody will want to see it, here’s my implementation of those 3 functions:

bool UInteractionBase::IsSupportedForNetworking() const
{
	return true;
}

bool UInteractionBase::CallRemoteFunction(UFunction* Function, void* Parms, FOutParmRec* OutParms, FFrame* Stack)
{
	auto* owner = Cast<AActor>(GetOuter());
	if (ensure(owner != nullptr))
	{
		UNetDriver* netDriver = owner->GetNetDriver();
		if (ensure(netDriver != nullptr))
		{
			netDriver->ProcessRemoteFunction(owner, Function, Parms, OutParms, Stack, this);
			return true;
		}
	}
	return false;
}

int32 UInteractionBase::GetFunctionCallspace(UFunction* Function, void* Parameters, FFrame* Stack)
{	
	auto* owner = Cast<AActor>(GetOuter());
	check(owner != nullptr);
	return (owner ? owner->GetFunctionCallspace(Function, Parameters, Stack) : FunctionCallspace::Local);
}
1 Like

Not a very satisfying answer, but this appears to be a bug or limitation in Unreal…

In Class.cpp, see SetUpRuntimeReplicationData. This function relies on PropertyLink to not be null despite PropertyLink not being used by this method. If the body of this function is skipped, NetFields will never be populated which is required for there to be a net cache for that class.

Although I don’t suggest it, this can be hacked around pretty easily. This code below will force the NetField’s to be populated:

auto oldPropLink = StaticClass()->PropertyLink;
StaticClass()->PropertyLink = StaticClass()->PropertyLink ? StaticClass()->PropertyLink : (UProperty*)1;
StaticClass()->SetUpRuntimeReplicationData();
StaticClass()->PropertyLink = oldPropLink;

It’s a hacky proof of concept that appears to work. I have no idea if there are consequences I’m unaware of. I’m going to just use a dummy UPROPERTY though, although I’d suggest the unreal dev’s look into the issue and double check if my assumptions about that null check being not-needed are correct. :slight_smile:

3 Likes

OMG Thanks,I spend 3 weeks to fix UObject RPC issue

A parameter-less UPROPERTY is not useless, it’s a macro that adds reflection to that variable, which is sometime needed.