GrabComponent DEPRICATED

Unreal Engine is currently on Version 4.14.3 and as I searched the code looking for “GrabComponent” I couldn’t find the reference as described in the lesson, but instead found:

HandleComp->GrabComponentAtLocationWithRotation(ComponentToGrab, NAME_None, -ComponentToGrab->GetOwner()->GetActorLocation(), ComponentToGrab->GetOwner()->GetActorRotation());

So I substituted the following in my code instead, tested, and everything works as expected. I’m sure the code supplied in the lesson still works, but I felt I wanted to be working with current info.

// If we hit something then attach a physics handle
if (ActorHit){
	PhysicsHandle->GrabComponentAtLocationWithRotation(
		ComponentToGrab, 
		NAME_None, 
		ComponentToGrab->GetOwner()->GetActorLocation(), 
		ComponentToGrab->GetOwner()->GetActorRotation()
	);
}

If I misunderstand something, please let me know!

8 Likes
if (ActorHit)
{
	if (!PhysicsHandle) { return; }
	PhysicsHandle->GrabComponent(
		ComponentToGrab, 
		NAME_None, // No bones required
		ComponentToGrab->GetOwner()->GetActorLocation(),
		true // Allow rotation
	);
}

This is the way i have handled it and its the same as the course but however i havent updated since 4.13.1 so its a recent change.
This being the case the old method may not work anymore and so the new method will need to be observed in case of updating the unreal engine past the tutorial version.
I believe the way you have done it is the correct new way to do it @Spencer_Rozell

1 Like

This is why I couldn’t find an example of its use!

4 Likes

For now the code in the lecture will still work, but you get a warning in the output log if you compile it in Unreal. The warning says to use GrabComponentAtLocation or GrabComponentAtLocationWithRotation, and to update your code or it may fail in the future.

The code supplied by Spencer is what I used also. By hovering over GrabComponentAtLocationWithRotation I found out the last variable it wanted was an FRotator so ComponentToGrab->GetOwner()->GetActorRotation() is the way to go.

The GrabComponentAtLocation method does not have a variable to designate rotation, so I do not know if that will work.

1 Like

Upon seeing the deprecation notice, I first tried the simple replacement without rotation specification:

    if (ActorHit) {
        UPrimitiveComponent* ComponentToGrab = LineTraceHit.GetComponent();
        
        PhysicsHandle->GrabComponentAtLocation(
            ComponentToGrab,
            NAME_None,
            ComponentToGrab->GetOwner()->GetActorLocation()
        );
    }

But, I found that the grabbed object’s rotation would not be constrained, which means it will dangle from the grab point if the center of gravity is higher (which it almost certainly is, if the grab point or origin is at the base). So I used the other replacement version that takes a rotation, and set it to all zeros:

    if (ActorHit) {
        UPrimitiveComponent* ComponentToGrab = LineTraceHit.GetComponent();
        
        PhysicsHandle->GrabComponentAtLocationWithRotation(
            ComponentToGrab,
            NAME_None,
            ComponentToGrab->GetOwner()->GetActorLocation(),
            FRotator(0.0f, 0.0f, 0.0f)
        );
    }

This seems to have the same behaviour as Ben shows in the video.

1 Like

You can also use the rotation of the object so it remains in whatever rotation the object was in before you picked it up.

1 Like

If you like you can also set the grabbed object’s location to 0 inside the tick via

“PhysicsHandler->SetTargetRotation(FRotator(0.0f, 0.0f, 0.0f));”

That way the object rotates to it’s default rotation, no matter how it was when you picked it up.

Alternatively you could also create a new input mapping for “Center Rotation” and bind a new method to that action so it centers out the object while you are holding it and press F for example.

I just did that for practice and it works nice :slight_smile:

void UGrabber::CenterGrabbedObject()
{
	if (PhysicsHandler->GrabbedComponent)
	{
		PhysicsHandler->SetTargetRotation(FRotator(0.0f, 0.0f, 0.0f));
	}
}

InputComponent->BindAction("CenterGrabbedObject", IE_Pressed, this, &UGrabber::CenterGrabbedObject);

Saved again :slight_smile:

Now in 4.16. you should use GrabComponentAtLocation or GrabComponentAtLocationWithRotation to avoid a compiler error.

Compiler Error in 4.16.x in the Editor after compiling with GrabComponent():

CompilerResultsLog:Error: Error C:\Users\bensc\Documents\repos\Escape\EscapeGame\Source\EscapeGame\Grabber.cpp(92) : warning C4996: 'UPhysicsHandleComponent::GrabComponent': Please use GrabComponentAtLocation or GrabComponentAtLocationWithRotation Please update your code to the new API before upgrading to the next release, otherwise your project will no long
er compile.
CompilerResultsLog:Error: Error C:\Program Files\Epic Games\UE_4.16\Engine\Source\Runtime\Engine\Classes\PhysicsEngine/PhysicsHandleComponent.h(89) : note: Siehe Deklaration von "UPhysicsHandleComponent::GrabComponent"

Example:

// If we hit something then attach a physics handle
if (ActorHit){
	PhysicsHandle->GrabComponentAtLocationWithRotation(
		ComponentToGrab, 
		NAME_None, 
		ComponentToGrab->GetOwner()->GetActorLocation(), 
		ComponentToGrab->GetOwner()->GetActorRotation()
	);
}
3 Likes

Thank you! Easy fix.

Privacy & Terms