Hello I have been working on a little project and I tried implementing projectiles following the fps tutorial in the documentation. When I build the code and run the game I press the left mouse button and the amount of objects does not go up which implies that my character is not shooting. I will send here the code for my character and the projectile. A little insight would be much apreciated.
WeaponProjectile.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "WeaponProjectile.generated.h"
UCLASS()
class HUNTERTOWER_API AWeaponProjectile : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AWeaponProjectile();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
//Sphere Collision component
UPROPERTY(VisibleAnywhere, Category = Projectile)
USphereComponent* CollisionComponent;
//Projectile movement component
UPROPERTY(VisibleAnywhere, Category = Movement)
UProjectileMovementComponent* ProjectileMovementComponent;
//Projectile mesh
UPROPERTY(VisibleAnywhere, Category = Projectile)
UStaticMeshComponent* ProjectileMeshComponent;
//Projectile material
UPROPERTY(VisibleAnywhere, Category = Movement)
UMaterialInstanceDynamic* ProjectileMaterialInstance;
//Function that initializes the projectile's velocity in the shoot direction
//Function is responsible for launching the projectile
void FireInDirection(const FVector& ShootDirection);
};
WeaponProjectile.cpp
#include "WeaponProjectile.h"
// Sets default values
AWeaponProjectile::AWeaponProjectile()
{
// 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;
if (!RootComponent)
{
RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("ProjectileSceneComponent"));
}
if (!CollisionComponent)
{
//Use a sphere as a simple collision representation
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("SphereComponent"));
//Set sphere collision radius
CollisionComponent->InitSphereRadius(15.0f);
//Set the root component to be the collision component
RootComponent = CollisionComponent;
}
if (!ProjectileMovementComponent)
{
//Use this component to drive this projectile's movement
//check documentation for definition of these components
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileMovementComponent"));
ProjectileMovementComponent->SetUpdatedComponent(CollisionComponent);
ProjectileMovementComponent->InitialSpeed = 3000.0f;
ProjectileMovementComponent->MaxSpeed = 3000.0f;
ProjectileMovementComponent->bRotationFollowsVelocity = true;
ProjectileMovementComponent->bShouldBounce = true;
ProjectileMovementComponent->Bounciness = 0.3f;
ProjectileMovementComponent->ProjectileGravityScale = 0.0f;
}
if (!ProjectileMeshComponent)
{
//make sure to remove the type of the reference of the mesh
ProjectileMeshComponent = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ProjectileMeshComponent"));
static ConstructorHelpers::FObjectFinder<UStaticMesh>Mesh(TEXT("'/Game/OtherMeshes/Sphere.Sphere'"));
if (Mesh.Succeeded())
{
ProjectileMeshComponent->SetStaticMesh(Mesh.Object);
}
static ConstructorHelpers::FObjectFinder<UMaterial>Material(TEXT("'/Game/OtherMeshes/SphereMaterial.SphereMaterial'"));
if (Material.Succeeded())
{
ProjectileMaterialInstance = UMaterialInstanceDynamic::Create(Material.Object, ProjectileMeshComponent);
}
ProjectileMeshComponent->SetMaterial(0, ProjectileMaterialInstance);
ProjectileMeshComponent->SetRelativeScale3D(FVector(0.09f, 0.09f, 0.09f));
ProjectileMeshComponent->SetupAttachment(RootComponent);
}
}
// Called when the game starts or when spawned
void AWeaponProjectile::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AWeaponProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AWeaponProjectile::FireInDirection(const FVector& ShootDirection)
{
//You only needed to supply a launch direction because the projectile's speed is defined by (ProjectileMovementConmponent)
ProjectileMovementComponent->Velocity = ShootDirection * ProjectileMovementComponent->InitialSpeed;
}
here is the fire function I put in the Hunter.cpp (my character)
void AHunter::Fire()
{
//attempt to fire a projectile
if (ProjectileClass)
{
//get the camera transform
FVector CameraLocation;
FRotator CameraRotation;
GetActorEyesViewPoint(CameraLocation, CameraRotation);
//Set MuzzleOffset to spawn projectiles at a certain point in front of the camera
MuzzleOffset.Set(300.0f, 0.0f, 0.0f);
//Transform MuzzleOffset from camera space to world space
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset);
//Skew the aim to be slightly upwards
FRotator MuzzleRotation = CameraRotation;
MuzzleRotation.Pitch += 10.0f;
UWorld* World = GetWorld();
if (World)
{
FActorSpawnParameters SpawnParams;
SpawnParams.Owner = this;
SpawnParams.Instigator = GetInstigator();
//Spawn the projectile at the muzzle
AWeaponProjectile* Projectile = World->SpawnActor<AWeaponProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams);
if (Projectile)
{
//set the projectile's initial trajectory
FVector LaunchDirection = MuzzleRotation.Vector();
Projectile->FireInDirection(LaunchDirection);
}
}
}
}
and this was added to Hunter.h (my character)
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
//Projectile class to spawn
UPROPERTY(EditDefaultsOnly, Category = Projectile)
TSubclassOf<class AWeaponProjectile> ProjectileClass;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
//Function that handles firing projectiles.
UFUNCTION()
void Fire();
//Gun muzzle offset from the camera location
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
FVector MuzzleOffset;
};
Sorry for the long post and than you so much for the help. I’m rather new to the engine and I still have much to learn.