Download

Actor component isn't registered in blueprint (Not sure if bug)

Hi, I’ve create an actor and an ActorComponent that should move the actor like is done for CharacterMovementComponent.

All works when the CPP instance Actor is put in the world (using editor).

The problems occurs when I extend the actor from CPP using BP. When I insert this BP_Actor in the world (using editor) the actor remain stationary.

The tick function is running because in the message log I can see the position FVector (that return a position from 0, 0, 0 for Bp Actor, that is wrong because the Actor is not at center of world).

I think that the component is not registered correctly when the Actor is extended by BP because if I try to destroy the actor from the component I get this warning:
LogSpawn:Warning: Destroying /Game/MyTrackedPawnaa.Default__MyTrackedPawnaa_C, which doesn’t have a valid world pointer

This warning never occurs if I use directly the CPP actor.

Now I will post the entire code of Actor and Actor component. Thanks for help in advance.

ACTOR HEADER


class TANKS_API ATrackedPawn : public APawn
 {
     GENERATED_BODY()
 
 public:
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tank")
     class UBoxComponent* BoxComponent;
 
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tank")
     class UTrackedVehicleMovementComponent* TrackedVehicleMovementComponent;
 
 public:
     ATrackedPawn();
 
 public:
     UBoxComponent* GetBoxComponent() const {
         return BoxComponent;
     };
 };

ACTOR CPP


ATrackedPawn::ATrackedPawn()
     : Super()
 {
     PrimaryActorTick.bCanEverTick = true;
 
     BoxComponent = CreateDefaultSubobject<UBoxComponent>(TEXT("BoxComponent"));
     RootComponent = BoxComponent;
     BoxComponent->SetCollisionProfileName(TEXT("BlockAll"));
     BoxComponent->SetSimulatePhysics(false);
     BoxComponent->SetMobility(EComponentMobility::Movable);
 
     TrackedVehicleMovementComponent = CreateDefaultSubobject<UTrackedVehicleMovementComponent>(TEXT("TrachedVehicleMovementComponent"));
     TrackedVehicleMovementComponent->TrackedPawn = this;
 }

ACTOR COMPONENT HEADER


UCLASS(Blueprintable, BlueprintType, ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
 class TANKS_API UTrackedVehicleMovementComponent : public UActorComponent
 {
     GENERATED_BODY()
 
 public:
     UPROPERTY(BlueprintReadWrite, Category = "Tracked vehicle movement")
     class ATrackedPawn* TrackedPawn;
 
 public:    
     UTrackedVehicleMovementComponent();
 
     virtual void BeginPlay() override;
     
     virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override;
 };

ACTOR COMPONENT CPP


UTrackedVehicleMovementComponent::UTrackedVehicleMovementComponent()
     : Super()
 {
     PrimaryComponentTick.bCanEverTick = true;
 
 }
 
 void UTrackedVehicleMovementComponent::BeginPlay(){
     Super::BeginPlay();
 }
 
 void UTrackedVehicleMovementComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ){
     Super::TickComponent( DeltaTime, TickType, ThisTickFunction );
 
     if (TrackedPawn) {
         UBoxComponent* BoxComponent = TrackedPawn->BoxComponent;
         if (BoxComponent) {
             FVector BoxLocation(BoxComponent->GetComponentLocation());
             BoxLocation.X += 20.f;
             BoxComponent->SetWorldLocation(BoxLocation);
             UE_LOG(LogTemp, Error, TEXT("Tick:%s"), *BoxLocation.ToString());
         }
     }
 }

you are creating the Component by default in the actors constructor, so i would try set the UPROPERTY to “VisibleAnywhere” instead of “EditAnywhere” - maybe this helps already, but if you destroy this actor, you should try GetOwner() -> seems like your variable (TrackedPawn) is a nullptr due to the fact that your component still lives somewhere after the actor got destroyed or so.

You are not actually changing the root component location, but just a local copy of it:


FVector BoxLocation(BoxComponent->GetComponentLocation());

This statement declares a local FVector variable with the same coordinates of the BoxComponent (copy constructor). When you add 20.f to the X you are adding it to the local variable, not to the box location.

Sorry for the delay to respond, but I hadn’t the possibility to stay on PC on the past 2 days.

I’ve tried to set VisibleAnywhere as you have advised but nothing changes. Another thing is that I’m destroying the Actor from the ActorComponent only for test.

I’m changing the position because after making the copy of vector I will set it in the actor in the next line:


BoxComponent->SetWorldLocation(BoxLocation);

As I’ve said before the component change the actor location correctly if I insert the actor directly from CPP in the world (using the editor).

What can I do to find what cause this problem??

Thank you all for your response and support

I’ve fixed the problem by moving the following code from constructor in the Beginplay


if (TrackedVehicleMovementComponent) {
		TrackedVehicleMovementComponent->TrackedPawn = this;
	}