Collision when using attached actors

This is a fairly common question, I know, but I have not seen an answer that suggests a workaround. I have seen “this isn’t supported” stated in a few different ways.

I have multiple actors with collision shapes. They collide just fine on their own, but when they are attached to each other, collision stops working. What I have gathered from the other threads on this issue is that there is no “sweep” performed for attached actors.

I desperately need a workaround for this. Can anyone suggest anything that might work? At this point, I’ve lost over a week of work and am still stuck.

I am attaching the actors using the simplest method I know:

AttachRootComponentTo(root_actor, NAME_None, EAttachLocation::SnapToTarget);

I can post any other code that might help explain my particular situation, but there’s nothing fancy about it. It’s just a bunch of actors, each with one static mesh component, each with a custom collision shape, attached using the code above.

I am not using Physics, only the absolute basic collisions. I just need to have a method called when these attached actors collide.

I’m willing to hack around in the engine code to fix this if someone can point me to the right code. I am currently looking through USceneComponent::MoveComponent() but it isn’t very clear to me, yet, how/where the attached actors are moved.

I have a fix for this that works in my particular situation, maybe it will help someone with the same problem.

If you look at PrimitiveComponent.cpp, line 1415:

		FComponentQueryParams Params(Name_MoveComponent, Actor);
		FCollisionResponseParams ResponseParam;
		InitSweepCollisionParams(Params, ResponseParam);
		bool const bHadBlockingHit = GetWorld()->ComponentSweepMulti(Hits, this, TraceStart, TraceEnd, GetComponentRotation(), Params);

		if (Hits.Num() > 0)

This is the code used inside the MoveComponent() member of a primitive component. It sweeps the component and returns an array of hits in the “Hits” variable. So, my fix was to copy this code into my actor’s Tick() method, which is where I handle movement. Where I do the movement for the root component, I added a simple loop to perform this sweep for all attached actors:

UWorld *w = GetWorld();
TArray<FHitResult> hits;

// This is how I was already handling movement, just a simple velocity vector multiplied by the elapsed time this tick
// You may want to also set the "bSweep" parameter in MoveComponent() here, if your root actor has a collision shape
// My root actor is just an empty dummy used for attaching other things, so I do not sweep it
FVector move(velocity * delta_seconds);
RootComponent->MoveComponent(move, rotation);

// The "attached_actors" array is a TArray of AActor* that I fill as things are being attached
// There are other ways to get all attached actors if necessary
for (auto i : attached_actors)
{
    // Get the root USceneComponent of the attached actor and cast it to a UPrimitiveComponent
    UPrimitiveComponent *root = Cast<UPrimitiveComponent>(i->GetRootComponent());

    // Start of move
    FVector start(root->GetComponentLocation());

    // Some collision parameters, not sure what they do, just initialize them to defaults
    FComponentQueryParams cqparams(TEXT("sweep_params"), i);
    FCollisionResponseParams crparams;
    root->InitSweepCollisionParams(cqparams, crparams);

    // Sweep the component and fill "hits" with the results
    w->ComponentSweepMulti(hits, root, start, start + move, root->GetComponentRotation(), cqparams);

    if (hits.Num())
    {
        // You can handle the hits here or save them and deal with them later, etc...
        // You could also call DispatchBlockingHit() here if you want your actor's "on_hit" method to be called
    }
}

Keep in mind that this only handles the most simple type of collision, just “hits.” My project does not use physics, overlaps, etc, so if you want to make those work, you will need to dig deeper into the MoveComponent() code and see how they are handled for the root component and add that code to your loop.

Thanks for the solution, but still hope UE give an official solution like you did.

it does actually work for me as well. At least I get the hit results. But how do I continue? I want the root component (where the other actor is attached) to actually “feel” that there is something blocking the path. Calling DispatchBlockingHit doesn’t seem to work.

That just depends on how you want to handle the collision. Calling DispatchBlockingHit() will just cause the standard collision handling, which means the colliding actor’s “on hit” method will be called. You can do whatever you need to do in that method. If you want some kind of physics-based reaction, that’s going to be hard.

For example, say you have a character and he’s holding a sword. By default, if you have that sword “parented” to a character, it won’t collide with anything. Now, suppose you add this code to force the child actor to register collisions. It will work and when that sword collides with another actor, you’ll get an “on_hit” for the sword actor. But if you just tell the parent to stop moving (which is what UE4 normally does for “blocking” collisions), your whole character is going to be frozen in place because it’s blocked. That’s probably not what you want. You probably want to have another animation ready where the character’s arm rebounds back away from the collision, plus some code to do damage to what the sword hit, so on and so on.

There isn’t really a “stock” action that can be used when a parented actor collides, which (I believe) is why collisions aren’t enabled for parented actors by default. UE can’t just automatically do the right thing in this situation.

Thank you for answering! I see what you mean and this is exactly what I was experiencing. Could you may have a look at my thread with the detailed problem? Plasma/Energy Shield like in Star Wars - C++ - Unreal Engine Forums

Thank you very much and sorry for reviving this question.