Son
Son

Reputation: 1050

Atached Actor Mesh dont stick to Parent Actor

Context:

I'm creating some Actors (Shields) using C++ in ActorComponent (ShieldComponent) which is attached to Actor (Ship). When I move my Ship, Actors (Shields) stay in place on world (don't move with Ship).

What can be important: I don't call CreateShieldActor in Constructor, so I can't use ConstructorHelpers::FObjectFinder instead of StaticLoadObject/LoadObject to load Mesh/Material.

My C++ code for creation looks like this:

AShieldPart* UShieldComponent::CreateShieldActor(AActor* Owner, FString MeshName)
{
    //Create Shield Actor
    FVector Location = Owner->GetActorLocation();
    FRotator Rotator(0, 0, 0);
    FVector Scale(10, 10, 10);
    FActorSpawnParameters SpawnInfo;
    SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
    SpawnInfo.Owner = Owner;

    FTransform Transform(Rotator, Location, Scale);
    UClass * MeshClass = AShieldPart::StaticClass();

    AShieldPart* ShieldPart = GetWorld()->SpawnActor<AShieldPart>(MeshClass, Transform, SpawnInfo);

    //Attach Mesh to Shield Actor
    ShieldPart->AttachToActor(Owner, FAttachmentTransformRules(EAttachmentRule::KeepRelative, false));

    //Set Mesh for Shield
    ShieldPart->SetNewMesh(MeshName);

    //Set Material
    UMaterial* Material = Cast<UMaterial>(StaticLoadObject(UMaterial::StaticClass(), NULL, TEXT("/some/path")));
    ShieldPart->MeshComponent->SetMaterial(0, Material);

    return ShieldPart;
}


AShieldPart::AShieldPart()
{
    // 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;

    RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
    SetRootComponent(RootComponent);

    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    MeshComponent->SetupAttachment(RootComponent);
}

void AShieldPart::SetNewMesh(FString MeshName)
{
    UStaticMesh* Mesh = Cast<UStaticMesh>(StaticLoadObject(UStaticMesh::StaticClass(), NULL, *MeshName));
    //UStaticMesh* Mesh = LoadObject<UStaticMesh>(nullptr, *MeshName);
    MeshComponent->SetStaticMesh(Mesh);
    MeshComponent->SetCollisionProfileName(TEXT("BlockAll"));
    MeshComponent->SetNotifyRigidBodyCollision(true);
    MeshComponent->SetSimulatePhysics(true);
    MeshComponent->SetEnableGravity(false);

    MeshComponent->RegisterComponent();
}

That it would be more interesting, when I create that Actors (Shields) using BP all works fine...

enter image description here

Upvotes: 1

Views: 5902

Answers (1)

Son
Son

Reputation: 1050

The solution turned out to be eliminating the USceneComponent as a RootElement. The main element must be UStaticMeshComponent, then it can attached to the parent element (Ship).

AShieldPart::AShieldPart()
{
    // 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;

    // Creating MeshComponent and attach to RootComponent
    MeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("MeshComponent"));
    RootComponent = MeshComponent;
    MeshComponent->AttachToComponent(RootComponent, FAttachmentTransformRules(EAttachmentRule::SnapToTarget, true));

    ...

Upvotes: 4

Related Questions