The Carried Resource: Spawn at a Socket, Attach, and Drop

How the harvested item is spawned, attached to a skeletal mesh socket, and dropped in Unreal Engine: an Extracted Resource component that rides the carried actor, server-side spawn and ownership, and a collision swap so the haul never shoves the worker but still stacks on the pile.

When a worker finishes harvesting, an item appears in its hands and travels home. That item is a normal actor with one component on it, spawned, attached, and dropped by the Gatherer. This card covers how the carried resource is built and handled. It is part of Resource Gathering AI in Unreal Engine and follows The Resource component, whose extraction is what triggers the spawn.

A carryable extracted-resource actor in Unreal Engine with its mesh collision disabled and the Extracted Resource component added

Spawn at the socket, then attach

The moment extraction completes, the Gatherer spawns the assignment’s ExtractedResourceActorClass at the worker’s carry socket and snaps it on:

USkeletalMeshComponent* Mesh = Cast<ACharacter>(GetOwner())->GetMesh();
FTransform SocketTransform = Mesh->GetSocketTransform(ActiveAssignment.ResourceSocketName);

SpawnedExtractedResource = GetWorld()->SpawnActor<AActor>(
    ActiveAssignment.ExtractedResourceActorClass,
    SocketTransform.GetLocation(), SocketTransform.GetRotation().Rotator(), SpawnParams);

SpawnedExtractedResource->SetOwner(GetOwner()->GetOwner());   // the player's controller
SpawnedExtractedResource->SetReplicates(true);
SpawnedExtractedResource->SetReplicateMovement(true);

SpawnedExtractedResource->AttachToComponent(
    Mesh, FAttachmentTransformRules::SnapToTargetNotIncludingScale, ActiveAssignment.ResourceSocketName);

Spawning it at the socket transform first and then attaching avoids a one-frame pop from the world origin. The owner is set to the Gatherer’s owner (the player controller), and replication is turned on, so the item exists and moves the same on every client. This spawn-and-attach is one Behavior Tree task:

The try-spawn-extracted-resource Behavior Tree task calling TrySpawnExtractedResourceAndAttachToCharacter

The socket decides where it rides

By default a spawned actor would sit at the character’s origin. To put the log on a shoulder or the rock on the head, add a socket to the character’s skeletal mesh and name it. The walkthrough attaches one to the head bone; whatever you pick, its name goes into the assignment’s Resource Socket Name field, and the spawned item snaps to it.

A socket added to the head bone of the worker's skeletal mesh in the Unreal skeleton editor

The Extracted Resource component handles the drop

The carried actor itself carries one component, UExtractedResourceComponent. It holds a replicated reference back to the Gatherer and binds to its drop event:

void UExtractedResourceComponent::SetGatherer(UGathererComponent* Gatherer)
{
    if (!GetOwner()->HasAuthority() || !Gatherer) return;
    GathererOwner = Gatherer;
    GathererOwner->OnDroppedActor.AddDynamic(this, &UExtractedResourceComponent::OnDropped);
}

The Gatherer wires this up automatically right after spawning, if the actor has the component:

if (const auto ExtractedResourceComponent = Cast<UExtractedResourceComponent>(
        SpawnedExtractedResource->GetComponentByClass(UExtractedResourceComponent::StaticClass())))
    ExtractedResourceComponent->SetGatherer(this);

Collision off while carried, on when dropped

The carried mesh starts with collision disabled so it does not push the worker around in transit. When the worker drops it at home, the Gatherer broadcasts OnDroppedActor, the component’s OnDropped runs, and collision comes back, with one important exception:

void UExtractedResourceComponent::OnDropped()
{
    if (!GetOwner()->HasAuthority()) return;
    if (UStaticMeshComponent* MeshComponent = GetOwner()->FindComponentByClass<UStaticMeshComponent>())
    {
        MeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
        MeshComponent->SetCollisionResponseToChannel(ECC_Pawn, ECR_Ignore);
    }
}

The dropped item collides with the world (so it rests on the ground and stacks) but ignores the Pawn channel, so it never blocks or jostles the workers that keep walking through the drop zone. The drop itself is the loop’s last Behavior Tree task:

The drop-extracted-resource Behavior Tree task calling DetachExtractedResourceFromCharacter

The detach also hands the item to the stacking helper for placement, which is the subject of The drop-off pile.

What to take away

  • The carried item is spawned at the skeletal mesh socket and attached with SnapToTargetNotIncludingScale; the assignment’s Resource Socket Name decides where it rides.
  • It is spawned server-side, owned by the player controller, and replicated, so it looks the same everywhere.
  • UExtractedResourceComponent listens for the Gatherer’s drop event and re-enables collision while ignoring the Pawn channel, so hauls stack without shoving workers.

Read the ownership chain end to end in Multiplayer, or see where the dropped items land in The drop-off pile. The finished plugin is Resource Gathering Minions on FAB.

Frequently asked questions

How does the carried item attach to the worker?
The Gatherer reads the socket transform for the assignment's Resource Socket Name, spawns the Extracted Resource Actor there, and calls AttachToComponent with SnapToTargetNotIncludingScale on that socket. Add a socket to the character's skeletal mesh (the walkthrough uses the head bone) and put its name in the assignment so the item rides where you want.
Why disable collision on the carried actor?
So it does not shove the worker around while attached. The carried mesh starts with collision off; when it is dropped, the Extracted Resource component turns collision back on but sets the Pawn channel to Ignore, so the dropped item collides with the world and stacks but never blocks or jostles the workers walking past it.
What does the Extracted Resource component do?
It rides the carried actor and holds a replicated reference to the Gatherer that made it. It binds to that Gatherer's OnDroppedActor delegate, so when the worker drops its haul, the component runs OnDropped and re-enables collision. If the carried actor has this component, the Gatherer wires it up automatically on spawn.
Who owns the spawned carried actor?
The Gatherer sets the carried actor's owner to its own owner, the player's controller, and turns on replication and replicated movement. That keeps the ownership chain intact and makes the item appear and move identically on every client.