Hey all,
So I’m making a tank battle game and I’m trying to ray cast from my crosshair to any visible object in the world then return the location of that object to the editor log which does work when I’m asking to to report PlayerCameraLocation but when I try and ask it to report the location of an objec in the world relitive to the location of my crosshair I get a huge X location value and no Y or Z location values here’s my TankPlayerContoller.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Battletank.h"
#include "TankPlayerController.h"
void ATankPlayerController::BeginPlay()
{
Super::BeginPlay();
UE_LOG(LogTemp, Warning, TEXT("Player Controller Begin Play"));
auto ControlledTank = GetControlledTank();
if (!ControlledTank)
{
UE_LOG(LogTemp, Warning, TEXT("Tank is not Controlled"))
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Player Controller is controlling %s"), *ControlledTank->GetName());
}
}
//Telling the editor/game to override Event_tick and start aiming at crosshair and logging values
void ATankPlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
AimAtCrossHair();
}
void ATankPlayerController::AimAtCrossHair()
{
if (!GetControlledTank())
{
return;
}
FVector HitLocation;
if (GetSightRayHitLocation(HitLocation))
{
UE_LOG(LogTemp, Warning, TEXT("Hitting %s"), *HitLocation.ToString())
}
}
ATank* ATankPlayerController::GetControlledTank() const
{
return Cast<ATank>(GetPawn());
}
//Craeting paramaters to get viewport and location of the crosshair in the world and logging results
bool ATankPlayerController::GetSightRayHitLocation(FVector& HitLocation) const
{
int32 ViewPortSizeX, ViewPortSizeY;
GetViewportSize(ViewPortSizeX, ViewPortSizeY);
auto ScreenLocation = FVector2D(ViewPortSizeX * CrossHairXLocation, ViewPortSizeY * CrossHairYLocation);
FVector LookDirection;
if (GetLookLocation(ScreenLocation, LookDirection))
{
return true;
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Deproject Failed!"))
}
GetLookVectorHitLocation(LookDirection, HitLocation);
return true;
}
//Getting the location of where player is looking in the world
bool ATankPlayerController::GetLookLocation(FVector2D ScreenLocation, FVector& LookDirection) const
{ FVector CameraWorldLocation;
return DeprojectScreenPositionToWorld(ScreenLocation.X,
ScreenLocation.Y,
CameraWorldLocation,
LookDirection);
}
bool ATankPlayerController::GetLookVectorHitLocation(FVector LookDirection, FVector & HitLocation) const
{
//Creating Ray-cast and returning true after hitting an visable object in the world.
FHitResult HitResult;
auto StartLocation = PlayerCameraManager->GetCameraLocation();
auto EndLocation = StartLocation + (LookDirection * LineTraceEnd);
if (GetWorld()->LineTraceSingleByChannel(
HitResult,
StartLocation,
EndLocation,
ECollisionChannel::ECC_Visibility)
)
HitLocation = HitResult.Location;
return true;
}
and here’s my TaankPlayerController.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Tank.h"
#include "GameFramework/PlayerController.h"
#include "TankPlayerController.generated.h"
/**
*
*/
UCLASS()
class BATTLETANK_API ATankPlayerController : public APlayerController
{
GENERATED_BODY()
public:
//Use Tank.h to find ATank then get the tank controlled by a human player
ATank* GetControlledTank() const;
//Override the beginplay() function
virtual void BeginPlay() override;
//Override the Event_Tick() function
virtual void Tick(float DeltaTime) override;
//Create function to aim at crosshair widget
void AimAtCrossHair();
private:
bool GetSightRayHitLocation(FVector& HitLocation) const;
UPROPERTY(EditAnywhere)
float CrossHairXLocation = 0.5;
UPROPERTY(EditAnywhere)
float CrossHairYLocation = 0.333;
bool GetLookLocation(FVector2D ScreenLocation, FVector& LookDirection) const;
bool GetLookVectorHitLocation(FVector LookLocation, FVector& HitLocation) const;
UPROPERTY(EditAnywhere)
float LineTraceEnd = 1000000.f;
};