Download

Attaching an Actor to a socket on a skeletal mesh from within the Actor class

Hi.

I’ve got a ACharacter (SamuraiCharacter) and also an AActor (Weapon.cpp). The Weapon class is the base class for a number of blueprints each representing a different weapon.
In the Weapon class I get hold of the PlayerCharacter and the CharacterMesh and I access the right hand socket.
My question and issue is looking at the Actor class api on unreal there is an AttachToActor and AttachToComponent function.

In BeginPlay in Weapon.cpp I’ve tried:

AttachToActor(CharacterMesh, EAttachLocation::SnapToTargetIncludingScale, TEXT(“Right_Hand_Object_Socket”));

Understandably I get an error because CharacterMesh is of type USkeletalMeshComponent and it’s expecting an AActor.

And the reason I’m hoping to do this from within the Weapon class and not the SamuraiCharacter class is because in the Samurai class i’d have to somehow get a reference to each separate weapon blueprint and I find that harder to do.

Thx.

You said yourself there is an AttachToComponent function. Why not use it?

Oh yeah. Thanks that worked. I’m just using a standard Sphere Component as the Actor for testing.

For some reason tho

AttachToComponent(CharacterMesh, FAttachmentTransformRules::SnapToTargetIncludingScale… )

is breaking my 3rd person character movement.

When I use ‘W’, etc. it won’t move forward or back and is just moving in weird directions.

There is a post maybe its to do with the collision channels and in my Actor class the root component is set to a USphereComponent.

If I change Snaptotargetincludingscale to KeepWorldTransform the character can then move again but the Actor isn’t attached directly to the socket it just maintains its location in the world.

I did set all the collision channels to “Ignore” on the Actor because I thought that might be the issue. But no luck. And I tried changng the collisionn channels on the character to ignore but then it just kept falling through the floor (because I’m assuming the floor was no longer blocking)

Thanks.

sorry can’t help you with that. But turning off the collisions on the actor (weapon) should work. Make sure you do that on all components. Is something attached to the weapon? maybe something invisible

Hi.

So this is my code (it extends AActor).

I’m not sure it has anything to do with the collision channel because I got rid of the collision component entirely and still had the same issue where the character just doesn’t move properly and the camera also seems to be affected.

I do wonder whether attaching an Actor to a socket should be done from within the Character class and not from within the Actor class itself (ie ‘this’).

I’m pretty sure I haven’t done anything problematic with the socket either.

And I think i’m accessing the character, its mesh and the socket properly.

So if anyone sees anything obvious, yeah that’d be great.

ADevice::ADevice()

{

// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don’t need it.

PrimaryActorTick.bCanEverTick = true;

deviceBody = CreateDefaultSubobject<UStaticMeshComponent>("devicebody");
// when the device is clicked it enters the socket.
OnClicked.AddDynamic(this, &ADevice::OnClickDevice);

deviceCollComponent = CreateDefaultSubobject<USphereComponent>("Collision Component");

deviceCollComponent->SetSphereRadius(20);

deviceCollComponent->SetGenerateOverlapEvents(true);

deviceCollComponent->SetCollisionEnabled(ECollisionEnabled::QueryOnly);

deviceCollComponent->SetCollisionObjectType(COLLISION_DEVICE);

deviceCollComponent->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);

deviceCollComponent->SetCollisionResponseToChannel(COLLISION_DEVICE, ECollisionResponse::ECR_Ignore);

deviceCollComponent->OnComponentBeginOverlap.AddDynamic(this, &ADevice::OnCompBeginOverlap);

RootComponent = deviceCollComponent;

deviceBody->SetupAttachment(deviceCollComponent);

}

// Called when the game starts or when spawned

void ADevice::BeginPlay()

{

Super::BeginPlay();

ASamuraiCharacter* CharacterReference = Cast<ASamuraiCharacter>(GetWorld()->GetFirstPlayerController()->GetCharacter());

USkeletalMeshComponent* CharacterMesh = CharacterReference->GetMesh();

TArray<FName> sockets = CharacterReference->GetMesh()->GetAllSocketNames();

if(sockets[0] == TEXT("Right_Hand_Object_Socket"))

{

    UE_LOG(LogTemp, Warning, TEXT("socket"));

    AttachToComponent(CharacterMesh, FAttachmentTransformRules::SnapToTargetIncludingScale, TEXT("Right_Hand_Object_Socket"));

}

}

Never did things like that. If turning off the collision doesn’t help, then I can’t help you any further.

I would try to create the scenario in Blueprints first for faster testing.

So what I did was just included the line in BeginPlay SetActorCollisionEnabled to false and it worked. So obviously an issue with collisions. And all that code from my earlier post I left in. My question I guess is why if I’m using a collision channel that is meant to ignore everything did OnBeginOverlap fire and why did it take SetActorCollisonEnabled to false to properly disable the collisions. I would have thought setting the collision channel to ignore would have worked?

I had another look at your code. You only disabled the collision for the collision component. The Static Mesh component has a collision on its own in case the Static Mesh used has collision primitives setup or is set to MeshCollision.