I am officially stuck as I have honestly no idea what any of these lines are supposed to do (the explanation that Ben gives I find are too vague and without much context or repetitive use where I can’t really follow each line’s purpose).
I followed upto Lecture 139 and i only get the message LogTemp: Warning: Hit direction: X=1.000 Y=1.000 Z=1.000
in the Output Log (Please note that i am following the Archived course). Here are my files:
TankPlayerController.h:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "Tank.h"
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "TankPlayerController.generated.h" // must be the last include
/**
*
*/
UCLASS()
class BATTLETANK_API ATankPlayerController : public APlayerController
{
GENERATED_BODY()
private:
ATank* GetControlledTank() const;
virtual void Tick(float DeltaTime) override;
virtual void BeginPlay() override;
// Start the tank moving the barrel so that a shot would hit where
// the crosshair intersects the world
void AimTowardsCrosshair();
// Return an OUT parameter, true if hits landscape
bool GetSightRayHitLocation(FVector& OutHitLocation) const;
UPROPERTY(EditAnywhere)
float CrosshairXLocation = 0.5;
UPROPERTY(EditAnywhere)
float CrosshairYLocation = 0.33333;
UPROPERTY(EditAnywhere)
float LineTraceRange = 1000000;
bool GetLookDirection(FVector2D ScreenLocation, FVector& LookDirection) const;
bool GetLookVectorHitLocation(FVector LookDirection, FVector& HitLocation) const;
};
TankPlayerController.cpp:
// Fill out your copyright notice in the Description page of Project Settings.
#include "TankPlayerController.h"
void ATankPlayerController::BeginPlay()
{
Super::BeginPlay();
auto ControlledTank = GetControlledTank();
if (!ControlledTank)
{
UE_LOG(LogTemp, Warning, TEXT("PlayerController not possesing a tank"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("PlayerController possessing: %s"), *(ControlledTank->GetName()));
}
UE_LOG(LogTemp, Warning, TEXT("PlayerController BeginPlay"));
}
void ATankPlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
AimTowardsCrosshair();
// UE_LOG(LogTemp, Warning, TEXT("Player controller ticking"));
}
ATank* ATankPlayerController::GetControlledTank() const
{
return Cast<ATank>(GetPawn());
}
void ATankPlayerController::AimTowardsCrosshair()
{
if (!GetControlledTank()) { return; }
FVector OutHitLocation; // Out Parameter
if (GetSightRayHitLocation(OutHitLocation)) // Has "side-effect", is going to line trace
{
UE_LOG(LogTemp, Warning, TEXT("Hit direction: %s"), *(OutHitLocation.ToString()));
// Tell controlled tank to aim at this point
}
}
// Get world location if linetrace through crosshair, true if hits location
bool ATankPlayerController::GetSightRayHitLocation(FVector& OutHitLocation) const
{
OutHitLocation = FVector(1.0);
// Find crosshair position
int32 ViewPortSizeX, ViewPortSizeY;
GetViewportSize(ViewPortSizeX, ViewPortSizeY);
auto ScreenLocation = FVector2D(ViewPortSizeX * CrosshairXLocation, ViewPortSizeY * CrosshairYLocation);
// UE_LOG(LogTemp, Warning, TEXT("ScreenLocation: %s"), *(ScreenLocation.ToString()));
// de-project screen position of the crosshair to world direction
FVector LookDirection;
if (GetLookDirection(ScreenLocation, LookDirection))
{
// Line-trace along that LookDirection and see what we hit
//UE_LOG(LogTemp, Warning, TEXT("Look direction: %s"), *(LookDirection.ToString()));
GetLookVectorHitLocation(LookDirection, OutHitLocation);
}
return true;
}
bool ATankPlayerController::GetLookVectorHitLocation(FVector LookDirection, FVector& HitLocation) const
{
FHitResult HitResult;
auto StartLocation = PlayerCameraManager->GetCameraLocation();
auto EndLocation = StartLocation = (LookDirection * LineTraceRange);
if (GetWorld()->LineTraceSingleByChannel(HitResult, StartLocation, EndLocation, ECollisionChannel::ECC_Visibility))
{
HitLocation = HitResult.Location;
return true;
}
return false; // line trace didn't succeed
}
bool ATankPlayerController::GetLookDirection(FVector2D ScreenLocation, FVector& LookDirection) const
{
FVector CameraWorldLocation; // To be discarded
return DeprojectScreenPositionToWorld(ScreenLocation.X, ScreenLocation.Y, CameraWorldLocation, LookDirection);
}
The results were working upto the end result of Lecture 139 so now I have no clue of what broke here, as it compiles without errors, and from what it looks like I have written almost exactly what Ben wrote
Could I get some assistance to get this to a working result (where it registers basically 0 when pointing at the sky)?