Hi my blueprint seems to be setup right for my turret but when i drag it into the world the mesh spawns super far away from the turret which means the checks aren’t done when i am near the mesh they are only done when i am near the capsule which is invisible. any ideas how to fix this? thank you in advance
sure, i’ve also tried creating another turret from the c++ class and had the same issue although strangely it was at a different distance from the mesh
i get this C:\GameDev\Tanks\Source\Tanks\Pawns\Turret.cpp(15) : error C2248: ‘AVehicleBase::BaseMesh’: cannot access private member declared in class ‘AVehicleBase’
when trying to do that, i tried moving it the the public area but that didn’t work
so that does move it at the start of the game but i get this error Mobility of /Game/Maps/UEDPIE_0_Main.Main:PersistentLevel.BP_Tank_C_19 : Capsule Collider has to be ‘Movable’ if you’d like to move.
over and over again in the log but when i check the capsule collider in BP it is set to moveable
i know it says that but the only code i’ve changed is adding BaseMesh->SetRelativeLocation(FVector(0.f, 0.f, -70.f)); so i have no idea why the capsule is moving
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tanks/Pawns/VehicleBase.h"
// Sets default values
AVehicleBase::AVehicleBase()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Collider"));
BaseMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Base Mesh"));
BaseMesh->SetupAttachment(RootComponent);
TurretMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Turret Mesh"));
TurretMesh->SetupAttachment(BaseMesh);
ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Projectile Spawn Point"));
ProjectileSpawnPoint->SetupAttachment(TurretMesh);
}
void AVehicleBase::RotateTurret(FVector LookAtTarget)
{
//turn towards actor
FVector LookAtTargetClean = FVector(LookAtTarget.X, LookAtTarget.Y, TurretMesh->GetComponentLocation().Z);
FVector StartLocation = TurretMesh->GetComponentLocation();
FRotator TurretRotation = FVector(LookAtTargetClean - StartLocation).Rotation();
}
void AVehicleBase::Fire()
{
//instantiate bullet at projectile spawn point
UE_LOG(LogTemp, Warning, TEXT("Fire"));
}
void AVehicleBase::HandleDestruction()
{
//spawn particles, play sound, shake camera
//destroy self
//pawn turret spawn debris maybe
//set player to dead, kill functionality, make invicible, move to spawn point, and respawn if lives > 0
}
void AVehicleBase::BeginPlay()
{
Super::BeginPlay();
BaseMesh->SetRelativeLocation(FVector(0.f, 0.f, -70.f));
}
Tank.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tank.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
void ATank::CalculateMoveInput(float Value)
{
MoveDirection = FVector(Value * MoveSpeed * GetWorld()->DeltaTimeSeconds, 0, 0);
}
void ATank::CalculateRotateInput(float Value)
{
float RotateAmount = Value * TurnSpeed * GetWorld()->DeltaTimeSeconds;
FRotator Rotation = FRotator(0, RotateAmount, 0);
RotationDirection = FQuat(Rotation);
}
void ATank::Move()
{
AddActorLocalOffset(MoveDirection, true);
}
void ATank::Rotate()
{
AddActorLocalRotation(RotationDirection, true);
}
ATank::ATank()
{
SpringArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Spring Arm"));
SpringArm->SetupAttachment(RootComponent);
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
Camera->SetupAttachment(SpringArm);
}
// Called when the game starts or when spawned
void ATank::BeginPlay()
{
Super::BeginPlay();
PlayerControllerReference = Cast<APlayerController>(GetController());
}
void ATank::HandleDestruction()
{
Super::HandleDestruction();
}
// Called every frame
void ATank::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
Rotate();
Move();
if (PlayerControllerReference)
{
FHitResult TraceHitResult;
PlayerControllerReference->GetHitResultUnderCursor(ECC_Visibility, false, TraceHitResult);
FVector HitLocation = TraceHitResult.ImpactPoint;
RotateTurret(HitLocation);
}
}
// Called to bind functionality to input
void ATank::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &ATank::CalculateMoveInput);
PlayerInputComponent->BindAxis("Turn", this, &ATank::CalculateRotateInput);
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &ATank::Fire);
}
Turret.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Tanks/Pawns/Turret.h"
#include "Kismet/GameplayStatics.h"
#include "Tank.h"
void ATurret::BeginPlay()
{
Super::BeginPlay();
GetWorld()->GetTimerManager().SetTimer(FireRateTimerHandle, this, &ATurret::CheckFireCondition, FireRate, true);
Player = Cast<ATank>(UGameplayStatics::GetPlayerPawn(this, 0));
}
void ATurret::HandleDestruction()
{
Super::HandleDestruction();
Destroy();
}
// Called every frame
void ATurret::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!Player || ReturnDistanceToPlayer() > Range) { return; }
RotateTurret(Player->GetActorLocation());
}
void ATurret::CheckFireCondition()
{
// dont fire when no player
if (!Player) { return; }
// fire when inrange
if (ReturnDistanceToPlayer() < Range )
{
Fire();
}
}
float ATurret::ReturnDistanceToPlayer()
{
if (!Player)
{
return 0.0f;
}
return FVector::Distance(Player->GetActorLocation(), GetActorLocation());
}
Can’t see anything wrong with that and after looking more closely at your message.
Main:PersistentLevel.BP_Tank_C_19
That would mean a tank that’s already in the level. If you search for it in the outliner and then look at it’s components you should see that it’s capsule component is static rather than movable.