I'm trying to make a weapons switching mechanic in my game. My implementation is a data asset that contains an array of weapons with each weapon contatining the meshes, stats and a weapon actor component which has the fire function and trigger status. At runtime I have a pawn that loads the weapon, loads the meshes and create a new weapon component matching that of the one in the weapon data asset. My problem is that when I call the functions to change the state of the trigger member function as soon as the function is finished the variable seems to reset itself back to false leading to the tick function never firing.
Things I have tried: - Checking that the input is being registered (it is) - Stepping through the code to see if the tick function is being called (it is) - Restarting Unreal (had no effect)
Weapon Data Asset
USTRUCT(BlueprintType)
struct FWeaponBlueprint
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, Category=WeaponMeshes)
UStaticMesh* WeaponBody = nullptr;
UPROPERTY(EditAnywhere, Category=WeaponMeshes)
UStaticMesh* WeaponBase = nullptr;
UPROPERTY(EditAnywhere, Category=WeaponMeshes)
UStaticMesh* WeaponGun = nullptr;
UPROPERTY(EditAnywhere, Category=WeaponMeshes)
UStaticMesh* WeaponBarrel = nullptr;
UPROPERTY(EditAnywhere, Category=WeaponData)
FVector EndOfBarrel;
UPROPERTY(EditAnywhere, Category=WeaponData)
TSubclassOf<UHonkWeaponComponent> FiringMechanism;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float RPM;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float TurnRate;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float ProjectileSpeed;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float Damage;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float Range;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float ChargeSpeed;
UPROPERTY(EditAnywhere, Category=WeaponStats)
float ExplosionRange;
};
UCLASS(BlueprintType)
class HONK_API UHonkWeaponAsset : public UDataAsset
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere)
TMap<FName, FWeaponBlueprint> Weapons;
};
Weapon Component
void UHonkWeaponComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (Firing && LastFired <= 0.0f) // Firing is always false and never true
{
UE_LOG(LogTemp, Warning, TEXT("This function needs overriding"));
LastFired = FireRate;
}
if(LastFired > 0.0f)
{
LastFired -= DeltaTime;
}
}
void UHonkWeaponComponent::SetTriggerStatus(bool status)
{
this->Firing = status; // This get's called no problem
}
Pawn Class
void AHonkPawn::SetWeapon(FName weapon, bool inConstructor)
{
if(WeaponAsset != nullptr)
{
if(WeaponAsset->Weapons.Contains(weapon))
{
EndOfBarrel->SetRelativeLocation(WeaponAsset->Weapons[weapon].EndOfBarrel);
if (!inConstructor)
{
WeaponComp = WeaponAsset->Weapons[weapon].FiringMechanism; //This is the weapon component within the data asset
WeaponInstance = NewObject<UHonkWeaponComponent>(WeaponComp);
UE_LOG(LogTemp, Display, TEXT("Weapon Instance: %s"), ((WeaponInstance != nullptr) ? TEXT("SUCCEEDED") : TEXT("FAILED")))
}
if(UStaticMesh* mesh = WeaponAsset->Weapons[weapon].WeaponBody) { WeaponBodyMesh->SetStaticMesh(mesh); }
if(UStaticMesh* mesh = WeaponAsset->Weapons[weapon].WeaponBase) { WeaponBaseMesh->SetStaticMesh(mesh); }
if(UStaticMesh* mesh = WeaponAsset->Weapons[weapon].WeaponGun) { WeaponGunMesh->SetStaticMesh(mesh); }
if(UStaticMesh* mesh = WeaponAsset->Weapons[weapon].WeaponBarrel){ WeaponBarrelMesh->SetStaticMesh(mesh); }
}
}
}
Apologies if the answer is obvious, I'm still getting to grips with UE4 and a lot of the concepts escape me. Thanks in advanced
EDIT: I figured it out. I missed registering the compontent
Updated Code:
WeaponComp = WeaponAsset->Weapons[weapon].FiringMechanism;
WeaponInstance = NewObject<UHonkWeaponComponent>(this, WeaponComp, WeaponComp->GetFName());
WeaponInstance->RegisterComponent();