Replicated UFUNCTION causes crash

I am currently developing a custom component for grabbing Physics Objects. In there I have a replicated function:

UFUNCTION(NetMulticast, Reliable, WithValidation)
		void Multicast_SuccessfulGrab(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, FVector GrabLocation, FVector GrabbedActorPosition, FQuat GrabbedActorQuat, FTransform ComponentTransform);
	virtual bool Multicast_SuccessfulGrab_Validate(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, FVector GrabLocation, FVector GrabbedActorPosition, FQuat GrabbedActorQuat, FTransform ComponentTransform);
	virtual void Multicast_SuccessfulGrab_Implementation(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, FVector GrabLocation, FVector GrabbedActorPosition, FQuat GrabbedActorQuat, FTransform ComponentTransform);

when I call the function like so:

Multicast_SuccessfulGrab(
    InGrabID,
    InComponent,
    InBoneIndex,
    OutClosestPoint.ClosestWorldPosition,
    GrabbedActorTransform.GetLocation(),
    GrabbedActorTransform.GetRotation(),
    GetComponentTransform()
);

The engine crashes

MachineId:D5161B834062B979112122AC3C60BC5F
EpicAccountId:7bd2a856164d4a969a7c6708527b5871

Access violation - code c0000005 (first/second chance not available)

UE4Editor_FPSPhysHandleTest!UNetworkedVRPhysicsHandle::Multicast_SuccessfulGrab() [d:\jonasfiles\projects\unrealtestprojects\vrphysicshandle\fpsphyshandletest\intermediate\build\win64\ue4editor\inc\fpsphyshandletest\fpsphyshandletest.generated.cpp:139]
UE4Editor_FPSPhysHandleTest!UNetworkedVRPhysicsHandle::Server_AttemptGrab_Implementation() [d:\jonasfiles\projects\unrealtestprojects\vrphysicshandle\fpsphyshandletest\source\fpsphyshandletest\networkedvrphysicshandle.cpp:71]

fpsphyshandletest.generated.cpp:139 is the last line of the following code. I guess FindFunctionChecked() does not find a Function, resulting in the crash.

void UNetworkedVRPhysicsHandle::Multicast_SuccessfulGrab(uint8 InGrabID, UPrimitiveComponent* InComponent, int32 InBoneIndex, FVector GrabLocation, FVector GrabbedActorPosition, FQuat GrabbedActorQuat, FTransform ComponentTransform)
{
    NetworkedVRPhysicsHandle_eventMulticast_SuccessfulGrab_Parms Parms;
    Parms.InGrabID=InGrabID;
    Parms.InComponent=InComponent;
    Parms.InBoneIndex=InBoneIndex;
    Parms.GrabLocation=GrabLocation;
    Parms.GrabbedActorPosition=GrabbedActorPosition;
    Parms.GrabbedActorQuat=GrabbedActorQuat;
    Parms.ComponentTransform=ComponentTransform;
    ProcessEvent(FindFunctionChecked(FPSPHYSHANDLETEST_Multicast_SuccessfulGrab),&Parms);
}

Hey ,

Can you let me know what is in this type? :

NetworkedVRPhysicsHandle_eventMulticast_SuccessfulGrab_Parms

NetworkedVRPhysicsHandle_eventMulticast_SuccessfulGrab_Parms is generated from the Engine. So I don’t really know what the type is. NetworkedVRPhysicsHandle is just the name of the class and Multicast_SuccessfulGrab is the name of the replicated function. So it’s probably just a struct to pass the function’s parameters into the ProcessEvent function.

I tried to go the Declaration or Definition of NetworkedVRPhysicsHandle_eventMulticast_SuccessfulGrab_Parms in Visual Studio, but VS could not find it. I looked into the header files included at the top of the generated .cpp file, but they are basically empty. Is there any other way I could try to find out what that type is?

I don’t think that NetworkedVRPhysicsHandle_eventMulticast_SuccessfulGrab_Parms exists in the engine. How did you decide to use it? Are you following a tutorial?

Sorry, that I did not clarify that the type is automatically generated by the engine during compilation. I neither decided to use it nor am I following a tutorial. The type is clearly generated by the engine or the unreal header tool or something similar. I did not write the code, I just happened to find it inside a generated .cpp file in the Intermediate folder of my project. I found it because it is the topmost file in the callstack of the error message.

I totally forgot to greet you. So… Hi :slight_smile:

I am really happy that you were able to respond to the issue that quickly. It is always good to tackle an issue with the help of others. I hope you are having a great day.

Oh, I see.

Alright, give me a few minutes and I’ll see if I can replicate the issue.

When you are calling:

 Multicast_SuccessfulGrab(
     InGrabID,
     InComponent,
     InBoneIndex,
     OutClosestPoint.ClosestWorldPosition,
     GrabbedActorTransform.GetLocation(),
     GrabbedActorTransform.GetRotation(),
     GetComponentTransform()
 );

Do you verify that pointers exist? Such as:

void AAH475014Character::TestCall( )
{
	// Guessing here
	UPrimitiveComponent *Comp = GetMesh( );
	if( Comp )
	{
		// Guessing here as well
		FTransform CompTransform = Comp->GetRelativeTransform( 	);
		uint8 GrabID = 1; // GetGrabID( ) : (hypothetical)
		int32 BoneIndex = 1; // GetBoneIndex( Comp ) : (hypothetical)

           // Not sure where this comes from or if its an object (pointer)
		if( OutClosestPoint )
		{
			FVector GrabLocation = OutClosestPoint.ClosestWorldPosition;
			if( GrabbedActor )
			{
				FVector GrabbedActorPosition = GrabbedActor->GetActorLocation();
				FQuat GrabbedActorQuat = GrabbedActor->GetActorRotation();
				Multicast_SuccessfulGrab( GrabID, Comp, BoneIndex, GrabLocation, GrabbedActorPosition, GrabbedActorQuat, CompTransform );
			}
		}
	}
}

I ask because my guess for the access violation is that somewhere along the way, there is a nullptr being used.

Yes, the pointer used in that function is checked beforehand.

If you want to, I could send you a download link for my UE4 project.

Yeah, we can try that.

[Download Link][1]

After opening the project and compiling, you should be able to just hit play. You will notice a Collision Sphere set up in front of the Pawn. Just go to one of the white Physics Cubes and left click to Grab. If you successfully Grab an Object, the Engine should crash immediately.

Let me know if you need anymore info. Additionally please let me know when your download finishes, so I can remove the download link.

[1]:

I have the download. Will check out the issue now.

Hey ,

I am not 100% of the technical reason why this was a issue but from what I do understand, when the GrabbedActorQuat parameter was being replicated, there was something resulting in it checking as a nullptr.

You should be good to go by updating the following:

[NetworkedVRPhysicsHandle.h]

UFUNCTION(NetMulticast, Reliable, WithValidation)
	void Multicast_SuccessfulGrab(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, const FVector &GrabLocation, const FVector &GrabbedActorPosition, const FQuat &GrabbedActorQuat, const FTransform &ComponentTransform);
	virtual bool Multicast_SuccessfulGrab_Validate(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, const FVector &GrabLocation, const FVector &GrabbedActorPosition, const FQuat &GrabbedActorQuat, const FTransform &ComponentTransform);
	virtual void Multicast_SuccessfulGrab_Implementation(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, const FVector &GrabLocation, const FVector &GrabbedActorPosition, const FQuat &GrabbedActorQuat, const FTransform &ComponentTransform);

[NetworkedVRPhysicsHandle.cpp]

bool UNetworkedVRPhysicsHandle::Multicast_SuccessfulGrab_Validate(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, const FVector &GrabLocation, const FVector &GrabbedActorPosition, const FQuat &GrabbedActorQuat, const FTransform &ComponentTransform)
{
	return true;
}

void UNetworkedVRPhysicsHandle::Multicast_SuccessfulGrab_Implementation(uint8 InGrabID, UPrimitiveComponent * InComponent, int32 InBoneIndex, const FVector &GrabLocation, const FVector &GrabbedActorPosition, const FQuat &GrabbedActorQuat, const FTransform &ComponentTransform )
{
	AActor* Owner = GetOwner();
	if (!Owner) { return; }

	FName BoneName = GetGrabbedBoneNameFromIndex(InBoneIndex);

	if (Owner->Role == ROLE_SimulatedProxy) // if neither Owning Client nor Server
	{
		GrabComponentAdvanced(InComponent, BoneName, GrabLocation, GrabbedActorPosition, GrabbedActorQuat, ComponentTransform);
		GrabID = InGrabID;
	}
	else if (Owner->Role == ROLE_AutonomousProxy) // if Owning Client
	{
		if (InGrabID == GrabID)
		{
			UpdateHandleData(GrabLocation, GrabbedActorPosition, GrabbedActorQuat, ComponentTransform, BoneName);
		}
	}
}

Thank you so much. I never would have thought it would work to replicate a reference. I thought another client wouldn’t be able to do anything with the memory location of a reference, but I am guessing that’s not how the replication works.

Anyways, thanks again for your help and finding a solution.