enter code hereHello, I’m trying to create my own radar in C++, based on the Actor distance and then filter the collected actors with tags. But it works not exactly it should.
.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "GameFramework/HUD.h"
#include "ZSFSNewHUD.generated.h"
/**
*
*/
UCLASS()
class ZSFS_I_API AZSFSNewHUD : public AHUD
{
GENERATED_BODY()
public:
AZSFSNewHUD();
// Called when the game starts or when spawned
virtual void BeginPlay() override;
// Called every frame
virtual void Tick(float DeltaSeconds) override;
/** Primary draw call for the HUD */
virtual void DrawHUD() override;
private:
/** Crosshair asset pointer */
class UTexture2D* RadarTex;
/** Crosshair asset pointer */
class UTexture2D* PlayerTex;
protected:
/*The start location of our radar*/
UPROPERTY(EditAnywhere, Category = Radar)
FVector2D RadarStartLocation = FVector2D(0.1f,0.165f);
/*The start location of our radar*/
UPROPERTY(EditAnywhere, Category = Radar)
FVector2D RadarStartLocationText = FVector2D(0.035f,0.02f);
/*The radius of our radar*/
UPROPERTY(EditAnywhere, Category = Radar)
float RadarRadius = 80.f;
/*The pixel size of the drawable radar actors*/
UPROPERTY(EditAnywhere, Category = Radar)
float DrawPixelSize = 10.f;
/*Returns the center of the radar as a 2d vector*/
FVector2D GetRadarCenterPosition();
/*Returns the center of the radar as a 2d vector*/
FVector2D GetRadarCenterPositionText();
/*Draws the radar*/
void DrawRadar();
/*Holds a reference to every actor we are currently drawing in our radar*/
TArray<AActor*> RadarActors;
/*Holds a reference to every actor we are currently drawing in our radar*/
TArray<AActor*> RadarAmmo;
/*The distance scale of the radar actors*/
UPROPERTY(EditAnywhere, Category = Radar)
float RadarDistanceScale = 55.0f;
float ObjectRadius;
/*Converts the given actors' location to local (based on our character)*/
FVector2D ConvertWorldLocationToLocal(AActor* ActorToPlace);
/*Draws the player in our radar*/
void DrawPlayerInRadar();
/*Draws the player in our radar*/
void AZSFSNewHUD::PerformRadarObjectFinfing();
/*Draws the raycasted actors in our radar*/
void DrawFoundActors();
/*Draws the raycasted actors in our radar*/
void DrawFoundAmmo();
void GetAllActors();
//TSubclassOf<ZSFSEnemy1BP> EnemyToFind;
//EnemyToFind = ZSFSEnemy1BP::StaticClass();
TArray<AActor*> ZSFSEnemy1;
//TSubclassOf<Box1BP> AmmoToFind;
//AmmoToFind = Box1BP::StaticClass();
TArray<AActor*> Ammo;
};
.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "ZSFS_I.h"
#include "ZSFSNewHUD.h"
AZSFSNewHUD::AZSFSNewHUD(){
// Set the crosshair texture
static ConstructorHelpers::FObjectFinder<UTexture2D> RadarTexObj(TEXT("/Game/AI_GameMode/radar11.radar11"));
RadarTex = RadarTexObj.Object;
// Set the crosshair texture
static ConstructorHelpers::FObjectFinder<UTexture2D> PlayerTexObj(TEXT("/Game/AI_GameMode/black-dot-hi.black-dot-hi"));
PlayerTex = PlayerTexObj.Object;
ObjectRadius = 5000.0f;
}
// Called when the game starts or when spawned
void AZSFSNewHUD::BeginPlay()
{
Super::BeginPlay();
/* UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), RadarActors);
UE_LOG(LogTemp,Warning,TEXT("Ammo is %d"), RadarActors.Num() );
for (AActor* It : RadarActors){
AActor* CurrentActor = It;
//In case the actor contains the word "Radar" as a tag, add it to our array
if (CurrentActor && CurrentActor->ActorHasTag("Radar")){
ZSFSEnemy1.Add(CurrentActor);
}
else if(CurrentActor && CurrentActor->ActorHasTag("Ammo")){
Ammo.Add(CurrentActor);
}
}
UE_LOG(LogTemp,Warning,TEXT("Ammo is %d"), ZSFSEnemy1.Num() );
UE_LOG(LogTemp,Warning,TEXT("Ammo is %d"), Ammo.Num() ); */
//UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACharacter::StaticClass(), ZSFSEnemy1);
//UE_LOG(LogTemp,Warning,TEXT("ZSFSEnemy1 is %d"), ZSFSEnemy1.Num() );
}
void AZSFSNewHUD::Tick(float DeltaTime) {
Super::Tick(DeltaTime);
GetAllActors();
}
void AZSFSNewHUD::DrawHUD(){
Super::DrawHUD();
DrawRadar();
DrawPlayerInRadar();
PerformRadarObjectFinfing();
if (ZSFSEnemy1.Num() > 0) {
DrawFoundActors();
}
if (Ammo.Num() > 0) {
DrawFoundAmmo();
}
//Empty the radar actors in case the player moves out of range,
//by doing so, we have always a valid display in our radar
//ZSFSEnemy1.Empty();
//Ammo.Empty();
}
FVector2D AZSFSNewHUD::GetRadarCenterPosition(){
//If the canvas is valid, return the center as a 2d vector
return (Canvas) ? FVector2D(Canvas->SizeX*RadarStartLocation.X, Canvas->SizeY*RadarStartLocation.Y) : FVector2D(0, 0);
}
FVector2D AZSFSNewHUD::GetRadarCenterPositionText(){
//If the canvas is valid, return the center as a 2d vector
return (Canvas) ? FVector2D(Canvas->SizeX*RadarStartLocationText.X, Canvas->SizeY*RadarStartLocationText.Y) : FVector2D(0, 0);
}
void AZSFSNewHUD::DrawRadar(){
FVector2D RadarCenter = GetRadarCenterPositionText();
// offset by half the texture's dimensions so that the center of the texture aligns with the center of the Canvas
const FVector2D RadarDrawPosition( (RadarCenter.X),(RadarCenter.Y));
// draw the radar
FCanvasTileItem TileItem1( RadarDrawPosition, RadarTex->Resource, FVector2D(150.0f, 150.0f), FLinearColor::White);
TileItem1.BlendMode = SE_BLEND_Translucent;
Canvas->DrawItem( TileItem1 );
}
void AZSFSNewHUD::DrawPlayerInRadar(){
FVector2D RadarCenter = GetRadarCenterPositionText();
const FVector2D RadarDrawPositionPlayer( (RadarCenter.X + 70.0f),(RadarCenter.Y + 70.0f));
// draw the player
FCanvasTileItem TileItem2( RadarDrawPositionPlayer , PlayerTex->Resource, FVector2D(10.0f, 10.0f), FLinearColor::White);
TileItem2.BlendMode = SE_BLEND_Translucent;
Canvas->DrawItem( TileItem2 );
}
void AZSFSNewHUD::GetAllActors() {
APawn* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
//Player->GetDistanceTo
for (TActorIterator<AActor> it(GetWorld()); it; ++it) {
float Distance = Player->GetDistanceTo(*it);
if (Distance <= ObjectRadius) {
if(RadarActors.Contains(*it)){
return;
}
RadarActors.AddUnique(*it);
UE_LOG(LogTemp, Warning, TEXT("RadarActors is %s"), *it->GetName());
//UE_LOG(LogTemp,Warning,TEXT("ZSFSEnemy1 is %d"), RadarActors.Num() );
//UGameplayStatics::GetAllActorsOfClass(GetWorld(), AActor::StaticClass(), RadarActors);
}
else {
RadarActors.Remove(*it);
//RadarActors.Empty();
}
}
}
void AZSFSNewHUD::PerformRadarObjectFinfing(){
if (RadarActors.Num() > 0) {
for (AActor* It : RadarActors) {
if (It && !It->IsPendingKill()) {
AActor* CurrentActor = It;
//if (RadarActors.Num() > 0) {
//In case the actor contains the word "Radar" as a tag, add it to our array
if (CurrentActor && CurrentActor->ActorHasTag("Radar")) {
ZSFSEnemy1.Add(CurrentActor);
}
else if (CurrentActor && CurrentActor->ActorHasTag("Ammo")) {
Ammo.Add(CurrentActor);
}
//}
}
}
}
//UE_LOG(LogTemp,Warning,TEXT("ZSFSEnemy1 is %d"), ZSFSEnemy1.Num() );
//UE_LOG(LogTemp,Warning,TEXT("Ammo is %d"), Ammo.Num() );
}
FVector2D AZSFSNewHUD::ConvertWorldLocationToLocal(AActor* ActorToPlace){
APawn* Player = UGameplayStatics::GetPlayerPawn(GetWorld(), 0);
if (Player && ActorToPlace){
//Convert the world location to local, based on the transform of the player
FVector ActorsLocal3dVector = Player->GetTransform().InverseTransformPosition(ActorToPlace->GetActorLocation());
//Rotate the vector by 90 degrees counter-clockwise in order to have a valid rotation in our radar
ActorsLocal3dVector = FRotator(0.f, -90.f, 0.f).RotateVector(ActorsLocal3dVector);
//Apply the given distance scale
ActorsLocal3dVector /= RadarDistanceScale;
//Return a 2d vector based on the 3d vector we've created above
return FVector2D(ActorsLocal3dVector);
}
return FVector2D(0,0);
}
void AZSFSNewHUD::DrawFoundActors(){
FVector2D RadarCenter = GetRadarCenterPositionText();
for (auto It : ZSFSEnemy1){
FVector2D convertedLocation = ConvertWorldLocationToLocal(It);
FVector tempVector = FVector(convertedLocation.X, convertedLocation.Y, 0.f);
//Subtract the pixel size in order to make the radar display more accurate
tempVector = tempVector.GetClampedToMaxSize2D(RadarRadius - DrawPixelSize);
//Assign the converted X and Y values to the vector we want to display
convertedLocation.X = tempVector.X;
convertedLocation.Y = tempVector.Y;
DrawRect(FLinearColor::Red, RadarCenter.X + convertedLocation.X + 75.0f, RadarCenter.Y + convertedLocation.Y + 75.0f, DrawPixelSize, DrawPixelSize);
}
}
void AZSFSNewHUD::DrawFoundAmmo(){
FVector2D RadarCenter = GetRadarCenterPositionText();
for (auto It : Ammo){
FVector2D convertedLocation = ConvertWorldLocationToLocal(It);
FVector tempVector = FVector(convertedLocation.X, convertedLocation.Y, 0.f);
//Subtract the pixel size in order to make the radar display more accurate
tempVector = tempVector.GetClampedToMaxSize2D(RadarRadius - DrawPixelSize);
//Assign the converted X and Y values to the vector we want to display
convertedLocation.X = tempVector.X;
convertedLocation.Y = tempVector.Y;
DrawRect(FLinearColor::Blue, RadarCenter.X + convertedLocation.X + 75.0f, RadarCenter.Y + convertedLocation.Y + 75.0f, DrawPixelSize, DrawPixelSize);
}
}
The code is compiled, but the actors are displayed that are at the beginning of the game and then it isn’t updated.