Setting box collision location relative to root component from C++

Hey, my goal is to have a C++ component that can be added to player. A component that creates a box collision from the C++ that is placed relatively to the player’s position with an X offset e.g. 75.

What I achieved is creating a C++ component and the box collision. What is not working for me is the box collision is somehow pinned to the world. It’s not moving with the player.

Not sure what you need, but here’s full code of the component and screens of how it looks like in the editor/game. The square box is the box collision. It isn’t moving at all.
Thanks in advance for the help. Let me know if you need more info.

image
image


// Header:

UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class ESCAPED_API UAC_Switchable : public UPrimitiveComponent {

  GENERATED_BODY()

public:
  UAC_Switchable();


  UPROPERTY(EditAnywhere)
  UBoxComponent *BoxCollision;

protected:
  virtual void BeginPlay() override;

public:
  virtual void
  TickComponent(float DeltaTime, ELevelTick TickType,
                FActorComponentTickFunction *ThisTickFunction) override;

private:
  void AddSwitchCollisionBox();
  void AdjustSwitchCollisionBoxLocation();
};

// Cpp

UAC_Switchable::UAC_Switchable() {
  PrimaryComponentTick.bCanEverTick = true;

  AddSwitchCollisionBox();
}

void UAC_Switchable::AddSwitchCollisionBox() {

  BoxCollision = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxCollision"));

  BoxCollision->SetHiddenInGame(false);
  BoxCollision->SetVisibility(true);
  BoxCollision->SetCollisionProfileName(TEXT("OverlapAll"));
  BoxCollision->OnComponentBeginOverlap.AddDynamic(
      this, &UAC_Switchable::OnBeginOverlap);

  AdjustSwitchCollisionBoxLocation();

  if (auto owner = GetOwner(); owner) {
    const auto rootComponent = owner->GetRootComponent();
    rootComponent->SetHiddenInGame(false);
    rootComponent->SetVisibility(true);

    LogHelper::Log(FString::Printf(TEXT("Adding collision box to %s"),
                                   *rootComponent->GetName()));

    BoxCollision->AttachToComponent(
        rootComponent, FAttachmentTransformRules::KeepRelativeTransform);

  } else {
    LogHelper::Log(TEXT("Not adding collision box"));
  }
}

void UAC_Switchable::AdjustSwitchCollisionBoxLocation() {

  auto boxTransform = FTransform();
  auto boxLocation = boxTransform.GetLocation();
  boxLocation.X += 75;

  LogHelper::Log(FString::Printf(TEXT("Changing X %f -> %f"),
                                 boxTransform.GetLocation().X, boxLocation.X));

  boxTransform.SetLocation(boxLocation);

  BoxCollision->SetRelativeTransform(boxTransform);
  LogHelper::Log(FString::Printf(
      TEXT("Set %f"), BoxCollision->GetRelativeTransform().GetLocation().X));
}

void UAC_Switchable::TickComponent(
    float DeltaTime, ELevelTick TickType,
    FActorComponentTickFunction *ThisTickFunction) {

  Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
  if (auto owner = GetOwner(); owner) {
    const auto rootComponent = owner->GetRootComponent();
    LogHelper::Log(
        FString::Printf(TEXT("Root X %f, box X %f"),
                        rootComponent->GetRelativeTransform().GetLocation().X,
                        BoxCollision->GetRelativeTransform().GetLocation().X));
  }
}

Well, made this work, not sure how.

Apparently when I remove the UPROPERTY from here

  UPROPERTY(EditAnywhere)
  UBoxComponent *BoxCollision;

then the box is correctly attached to the player and ‘follows’ it.

Does anyone know why is that? Why UPROPERTY breaks this behavior?

Did You Test For Example
UPROPERTY(EditAnywhere, Category = “BoxCollision”);
UBoxComponent *BoxCollision;
?