Logging Collisions with our Ray Casting
Continuing to work on our Building Escape game we need to get our character in game to be able to start “Reach”ing out and grabbing items. The first thing we need to make sure that we do is to that we need to make sure that our Ray Casting is working properly. We need to make sure that the reach distance we have set is the correct length. We will put a simple test in our code that will print to the output log within the UE4 Editor what it is that our Ray Casting has collided with. We need to set up our Ray Cast to go to a certain distance and we have that set up within our code already.
FVector LineTraceEnd = PlayerViewPointLocation + PlayerViewPointRotation.Vector() * Reach;
Also remember that we have in our header file Grabber.h
we also have the Reach
defined in our private members.
private:
float Reach = 100.f;
When starting to make the Ray Cast we know that the ray casting itself will be taking place within our world so first we have to use GetWorld()
then the new line of code that we are going to be looking at that goes after this looks something like this when it is all built out and we will go over each argument and what it means :
GetWorld()->LineTraceSingleByObjectType(
Hit,
PlayerViewPointLocation,
LineTraceEnd,
FCollisionObjectQueryParams(ECollisionChannel::ECC_PhysicsBody),
LineTraceParams
);
Looking at this block of code the first argument we see is the word Hit
this first argument asks for a FHitResult that we created and just declared it like so :
FHitResult Hit;
It is just a variable to be able to store the object that is being hit with the ray cast. The second argument asks for the starting point of the ray cast, for us this is going to be our player in game so we use PlayerViewPointLocation
as the starting point for our ray cast. The third argument is where the ray casting will end, what is the end point? We have that defined already within our LineTraceEnd
. Then the fourth and more confusing looking argument of them all, this is just simply asking for what objects is the ray casting looking for within our world. In our case we have our cylinder, and that cylinder has the collision settings set to “PhysicsActor” and the object type to “PhysicsBody”. Using the FCollisionObjectQueryParams
needs to take an argument itself and the argument that it needs is what type of “channel” should the ray cast be looking for. The “channel” refers to the Object Type, and because ECollisionChannel
is an “enum” we use the double colon (::) to access the members of it and tell it to look for collisions only with those objects that match the Object Type of “PhysicsBody”. The last and final argument of this LineTraceSingleByObjectType
is parameters for the collision query itself. An FCollisionQueryParams
needs to be used and this has its own syntax and set of arguments.
FCollisionQueryParams
(
FName InTraceTag,
bool bInTraceComplex,
const AActor * InIgnoreActor
)
This is the basic syntax for the FCollisionQueryParams
function, the first argument of FName InTraceTag
is asking if we are using any tags within our ray casting and we are not because we are using the ECollisionChannel so we won’t leave that blank but we will put an empty string in there. The second argument is a simple boolean asking whether or not we are using simple collisions within our UE4 editor, or if we are using “Visibility Collision”, this would come in handy if you were trying to say reach through the window in our door. Since we are using Simple Collision this is going to stay false
for us. The final argument is asking if there is any Actors within the world that need to be ignored. Our ray cast line when looked at closely within Unreal really starts from within our Default Pawn, making it that the first thing our ray cast will collide with is our self. So we have to make sure that our ray cast will ignore us when “Reaching” out. The final block of code within our game would look like this :
FCollisionQueryParams LineTraceParams(FName(TEXT("")), false, GetOwner());
Naming our Query Params lets us simply use LineTraceParams
within our LineTraceSingleByObjectType
function. With all set up our ray casting is ready to be tested so we need to log out to the output log what it is that our Player is collided with and able to interact with and eventually actually “Grab” the object. So we have our Hit
that is FHitResult
that is storing our info of what is being “Hit” with our ray cast, we just have to get the information from it so we will create an Actor to store it.
AActor* ActorThatWasHit = Hit.GetActor();
Now we can use this ActorThatWasHit
to be printed out to our output log, we will use a simple if statement just to protect us from it only running this when an Object is collided with.
if (ActorThatWasHit)
{
UE_LOG(LogTemp, Warning, TEXT("Line Trace has hit: %s"), * (ActorThatWasHit->GetName()))
}
We compile our code now within our UE4 editor and hit play, when we move around with our player and we collide into our cylinder object the output log will print out the name of the object that was hit :
Line Trace has hit : Cylinder_2
Our Ray Casting is working and running properly the way we want it to, now we can see our far our Reach
is and can be adjusted if you want to, but now we can also see that our collisions are working properly and that we are colliding with only objects that have the PhysicsBody, this is important because the PhysicsBody is something that will be needed when we finally get our Player to grab the cylinder. We will continue to work on this Grabber component next week and also look at how we can use User Input to make Function Calls with Key mapping.