TIL: Learn to Code in C++ by Developing Your First Game (Section 3, Lectures 71-75)

I’ve only been able to make it through about one and a half of these a night the past few nights. The more exhausted you get, the harder it is to take in increasingly technical concepts. The last lecture doesn’t make a ton of sense to me at all this fine dark almost 2AM, so I’m going to head to sleep now that I’ve got some basic collision detection happening.

Section: 3 – Building Escape – Your First Unreal / C++ Game

Lecture 71: Getting Player Viewpoint

GetPlayerViewPoint()

We want to cast a line from the player so that we can detect what we’re looking at. This will later allow us to do an if statement so that if an object is movable, we can move it.

I must admit, I don’t fully understand just yet why this is such a big deal, but Ben seems quite upset that our void getter functions are modifying data rather than simply fetching it. This would appear to be quite uncommon and so we’ll treat this code slightly different to help make it more readable. It’s weird to have to create variables just so we can fill them up by using a getter… so we want to help make this more obvious by using a macro that does nothing but will act somewhat as a comment.

At the top of Grabber.cpp we will:
#define OUT

and then inside the tick component we end up with

// Get player viewpoint this tick
FVector PlayerViewPointLocation;
FRotator PlayerViewPointRotation;
GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(
    OUT PlayerViewPointLocation,
    OUT PlayerViewPointRotation
    );

This serves no purpose other than annotation… we could in theory just comment the lines as well.

We also end up with:

// TODO log out to test
UE_LOG(LogTemp, Warning, TEXT("Location: %s, Rotation: %s"),
    *PlayerViewPointLocation.ToString(),
    *PlayerViewPointRotation.ToString()
    )

And while Ben “corrects” the formatting to eliminate bugs, I can confirm that it works fine as is — without eliminating the line breaks.

Lecture 72: Using DrawDebugLine

Here we create a debug line to create a vector between our position and an end point that we can visualize using DrawDebugLine().

I feel like Ben’s explanation on vectors confused me rather than reinforcing the knowledge I already have.

Basically you have a position (PlayerViewPointLocation), and you have the direction you are looking (PlayerViewPointRotation.Vector()). This will be a normalized vector, so when we multiply it by a “Reach” vector we will end up with a position that is “Reach” units away from the original position, in the direction that we were looking. This end position is our LineTraceEnd.

One quick way of commenting in VS, is to highlight the code you want to comment, press ctrl+k, then press ctrl+c

We appear to require the use of GetWorld() in our code as (I think) it signifies to the engine that we want to work in World Space and not in some sort of space such as Camera, or Local etc. DrawDebugLine() just seems to require it, though I’m not sure what alternatives could be used or why you would need an alternative.

Interestingly, it’s possible to do “hot compiles” … while in the middle of playing, you can go to Visual Studio, change a parameter, then go back to UE4 and “compile” to change how things such as the distance of the trace vector work on the fly. (It does take some time to compile though)

That trace seems to draw transparent no matter what value I give as a 4th channel :-/

Lecture 73: Line Tracing AKA Ray-Casting

Line tracing / ray casting isn’t a new concept for me. I’ve been working in film for years… ray tracing is quite common in rendering… though on a grander scale.

Keep in mind that the DebugLine is literally for debug purposes, it is not an actual ray-cast and doesn’t return information.

We will be aware of collision filtering with our line tracing. Specifically, we are going to be doing a trace, and checking to see if it’s a physics object. If yes, then we can pick it up, if no, then we can’t.

Simply check “simulate physics”, assign a reasonable mass, and then the actor will be converted to a “PhysicsBody”.

Lecture 74: LineTraceSingleByObjectType()

The goal by the end of this video is to have the Line trace print in the Output Log when we are colliding with physics objects.

LineTraceSingleByObjectType()
FCollisionQueryParams()

We do our line tracing in the world, so we first GetWorld() then using the -> we can look for line trace options. Multi will collect an array of multiple objects, but we want single, and we want to filter it by object type hense: LineTraceSingleByObjectType().

We also begin to use references now which are denoted by & marks.
-They cannot be nullptr or any other null value.
-Once assigned, they cannot be re-assigned.
-Use it just like you would the object itself.

One thing to be aware of, is that if you use // to comment, it will mean that when you’re attempting to get help on things that you’ve typed, it will often provide the comment on the line before. You can prevent this with /// commenting. This can be helpful before functions such as DrawDebugLine().

We need an FCollisionObjectQueryParams which is a struct that contains a list of object types the query is interested in.
FCollisionQueryParams(FName(TEXT("")), false, GetOwner()); we’re ignoring the FName usage at the moment, the false is used so that we turn off complex collisions, while GetOwner is used so that we avoid detecting the character.

When we want to print what we’ve hit we use:

AActor* ActorHit = Hit.GetActor();
    if (ActorHit) {
        UE_LOG(LogTemp, Warning, TEXT("Line trace hit: %s"),
            *(ActorHit->GetName())
            )
        }

It’s essential to include the ActorHit->GetName() in brackets before dereferencing. ActorHit->GetName() produces an FString which needs to be dereferenced. When I attempted to just do *Hit.GetActor()-GetName() it resulted in crashing UE4.

Lecture 75: REFERENCES & POINTERS

This was a tough 5 minutes to get through. Not only does my internet suck sometimes… like tonight… but I’m not good at taking in information from graphs like what was used here. I’m still not sure what the point of a reference is since it seems to basically be a duplicated way of just getting the original information, and… I’m still not too sure what a pointer represents. So hopefully this continues to get more clear as I work with them. If not…. well, I’m going to have to seek out some other documentation. Maybe this… for example.