Issues with UProjectileMovementComponent v ProjectileMovementComponent Setup in Blueprint

Hopefully, this question will be easier to answer than some of my previous questions…

In this project, I have set-up a class for a projectiles in game (QTBDWeaponProjectile), this is as shown below:

Header:

#pragma once

#include "QTBDItem.h"
#include "QTBDWeaponProjectile.generated.h"

/**
 * For all projectiles in Quest: To Be Defined.
 */
UCLASS()
class QUESTTOBEDEFINED_API AQTBDWeaponProjectile : public AQTBDItem
{
	GENERATED_BODY()
	
public:

	// Properties:

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Movement)
	class UProjectileMovementComponent* WeaponProjectileMovementComponent;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = ProjectileProperties)
	FVector DefaultProjectileScale;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = ProjectileProperties)
	float ProjectileLifespan;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = ProjectileProperties)
	float InitialProjectileSpeed = 6000.f;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = ProjectileProperties)
	float MaximumProjectileSpeed = 6000.f;

	// Methods:

	/** The default constructor for QTBDWeaponProjectiles. */
	AQTBDWeaponProjectile();
	
	virtual void BeginPlay()override;
};

Implementation:

#include "QTBDWeaponProjectile.h"
#include "QuestToBeDefined.h"
#include "Runtime/Engine/Classes/GameFramework/ProjectileMovementComponent.h"
#include "Runtime/Engine/Classes/Components/StaticMeshComponent.h"
#include "Runtime/Engine/Classes/Components/CapsuleComponent.h"

/** The default constructor */
AQTBDWeaponProjectile::AQTBDWeaponProjectile()
{
	// There were more lines here for initialisation of other components,
	// as well as setting-up WeaponProjectileMovementComponent to what I thought
	// made sense, this has been removed to keep it as similar to the Blueprint
	// implementation:
	WeaponProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(FName("WeaponProjectileMovementComponent"));
}

void AQTBDWeaponProjectile::BeginPlay()
{
	// So that projectiles are removed after a time:
	SetLifeSpan(ProjectileLifespan);
}

For reference, are the header and implementation files for QTBDItem, respectively:

#pragma once

#include "QuestToBeDefined.h"
#include "GameFramework/Actor.h"
#include "QTBDEntity.h"
#include "QTBDItem.generated.h"

/**
 * For all items in Quest: To Be Defined (such as projectiles, weapons, armour etc.).
 */
UCLASS()
class QUESTTOBEDEFINED_API AQTBDItem : public AActor
{
	GENERATED_BODY()

public:

	/** This flag will state whether the player is overlaping the ProximitySphere, the player can then pick up this item */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Flags)
	bool bIsPlayerOverlapingPickupSphere;

	/** The name of this particular item */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ItemFields)
	FString ItemName;

	/** The mass of this particular item, in kilograms */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ItemFields)
	float ItemMass;

	/** The cost to purchase this item, if being sold instead, it can be sold for 75% of this value */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = ItemFields)
	float ItemValue;

	/** This flag relates to whether this item has been picked up or not */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Flags)
	bool bHasBeenPickedUp;
	
	/** Event for blueprint to use, to carry out actions, when the item has been picked up */
	UFUNCTION(BlueprintNativeEvent, meta = (DisplayName= "On Item Pick up"), Category = Pickup)
	void OnItemPickup();
	
	/** Use this whenever this item is in the player's inventory */
	UFUNCTION(BlueprintCallable, meta = (DisplayName= "Has now been picked up"), Category = PickupValidation)
	void NowInPlayerInventory();
	
	/** Set the 'IsPlayerOverlapingPickupSphere' var. to true */
	UFUNCTION(BlueprintCallable, meta = (DisplayName= "Player is overlaping the pickup sphere"), Category = PickupValidation)
	void PlayerOverlapingPickupSphere();

	/** Set the 'IsPlayerOverlapingPickupSphere' var. to false */
	UFUNCTION(BlueprintCallable, meta = (DisplayName= "Player is not overlaping the pickup sphere"), Category = PickupValidation)
	void PlayerNotOverlapingPickupSphere();
	
	/** The standard constructor. */
	AQTBDItem();
};

#include "QTBDItem.h"
#include "QuestToBeDefined.h"

AQTBDItem::AQTBDItem()
{
	// The player will not be overlaping this item, upon the iteme spawning into the level
	bIsPlayerOverlapingPickupSphere = false;

	// The player can't have picked up this item yet either
	bHasBeenPickedUp = false;
}

void AQTBDItem::PlayerOverlapingPickupSphere()
{
	bIsPlayerOverlapingPickupSphere = true;
}

void AQTBDItem::PlayerNotOverlapingPickupSphere()
{
	bIsPlayerOverlapingPickupSphere = false;
}

// Implementation is provided in Blueprint for these functions:
void AQTBDItem::OnItemPickup_Implementation()
{

}

// Called whenever the item has been picked up, also fires off an event that blueprint can use:
void AQTBDItem::NowInPlayerInventory()
{
	bHasBeenPickedUp = true;

	// Call this event for blueprint to handle:
	OnItemPickup();
}

I have then created a Blueprint Class, that inherits from QTBDWeaponProjectile, leaving the values for WeaponProjectileMovementComponent at the default. Other components to visual this projectile and handle collision are added via Blueprint. Having this actor spawned into the world though, then having the engine simulate the level, shows the projectile as remaining stationary.

When I set-up a Blueprint that inherits from the Actor class though (adding components to it via Blueprint), as shown below…

…with the values for the ProjectileMovementComponent left at their defaults, allows for a projectile that, when spawned into the game world, moves as per the ProjectileMovementComponent (this is what is expected).

Please feel free to ask me any questions in relation to any details that I have missed.

I am not sure why this is, it would seem as though I am missing something. Could someone let me know what the issue is? Thanks in advance.

Set Velocity or Initial Speed higher. Or maybe set Gravity Scale to 0 to see if it effects.

I will try that .

Check other components and make sure Simulate Physic is disabled.

Also check if you have BP node overriding actor location.

By the way in the picture the parent of the BP is Actor instead of AQTBDWeaponProjectile, is that intentional? So basically you’re testing in an empty actor but still unable to make it move?

Also try disabling all collision from other components.

Hmm, the gravity scale was at 0 for some reason (not the default), but that had no effect. I tried leaving that at 0 and changing the initial/max speed to be higher, no effect, adjust the velocity as well as the initial/max speed also had no effect and setting the velocity high in the X value (to ~9000) still, has no effect.
I also tried a similar value for velocity in the other axes, but this also had no effect.

It’s a shame that the issue would not have that simple of a fix.

This is intentional, as the projectile shown in the image (with a parent class of Actor) moves as expected, but a Blueprint class inheriting from AQTBDWeaponProjectile (not shown) has the same setup (except with the ProjectileMovementComponent inherited from the parent class).

I will try that too.

That had no effect I’m afraid.

First create a brand new BP from AQTBDWeaponProjectile and try again. Sometimes hot-reload messes up BP and lost reference to components.

Secondly I’d suggest change EditAnywhere to VisibleAnywhere here:

   UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Movement)
   class UProjectileMovementComponent* WeaponProjectileMovementComponent;    

For components, EditAnywhere means you expect it to be reassigned with a different component. While in this case you just want to modify the properties. In my experience EditAnywhere also make the UI in Detail tab quite confusing.

Ah, thanks for that , I will try that shortly. It would also seem to be correct that you mention how it can ‘make the UI in the detail tab quite confusing’, as it seems to hide all of the properties when declared as I had, so I will be sure to change the use of the UPROPERTY macro and make a new Blueprint that inherits from AQTBDWeaponProjectile.

Can you please provide a screenshot of the blueprint class that inherits from your AQTBDWeaponProjectile class?

Hmm, the projectile is showing up in the world as expected, but when I drag and drop this new Blueprint from the content browser into the level, then simulate the level, the projectile still remains stationary.

I have a couple of screenshots of this new Blueprint for you to look at (showing the key details for each of the projectiles components):

BulletCollider:

BulletCore:

WeaponProjectileMovementComponent:

Please let me know if I am missing something, I appreciate your help so far at any rate :).

I think your Projectile is not ticking! Try to add the following line to the constructor of AQTBDWeaponProjectile:

PrimaryActorTick.bCanEverTick = true;

OK I found the issue. You’re missing Super::BeginPlay() in your AQTBDWeaponProjectile::BeginPlay()

That’s why the component didn’t Tick properly.

Thanks for your input minecrafter338, but I think is on to something with Super::BeginPlay()…

I have a feeling that will resolve the issue, I will test it out soon. Thanks for your help :).

I should have known that was the issue, I have had it occur before, then the issue was able to be resolved by just putting in a call to Super::BeginPlay().

Issues regarding not calling Super::BeginPlay()*.