top of page
  • Writer's pictureKelson Wysocki

Spring/Summer Project 2023 - Update 9

Updated: Jan 17

Hello everyone. For the last couple of weeks, I've been struggling to figure out the direction in which I want this project to go but in that time I have been prototyping different features to see how they feel. For this post, I wanted to focus on the teleport attack I created recently which can be seen in the following video.


The first step for this attack was deciding how the player would choose where they

wanted to be teleported. While holding down the teleport key it will look for a target (which will be discussed below) and once the key is released, if there is a chosen target, the player will be teleported. A bool value is used for input information with three triggers to get the correct input values, "Down"/"Hold" is true, and "Released" is false. "Down" is required to start the action and "Hold updates the targeting for each tick while the key is held. Connecting this to the Action Manager I created ensures that it doesn't cause problems with other actions the player can perform.


The next step for the teleport attack was to target enemies while the key was down. Using the dot product it was simple to set up a function that could determine which enemy the player was looking at.

TArray< AActor * > found_targets;
UGameplayStatics::GetAllActorsOfClass( GetWorld(),      
    Character::StaticClass(), found_targets );

FVector forward = parent->GetGimbal()->GetForwardVector();

float smallest = TNumericLimits< float >::Max();
Character *curr_target = nullptr;
for ( AActor *actor : found_targets ) {
    if ( actor == parent ) continue;

    Character *targetable = Cast< Character >( actor );
    if ( targetable->health <= 0 ) continue;

    FVector actor_location = actor->GetActorLocation();

    FVector direction = actor_location - player_location;

    float dot_result = UKismetMathLibrary::Abs( 
        FVector::DotProduct( forward, direction ) - 1.f );
    if ( dot_result >= smallest ) continue;

    if ( dot_result > 0.2f ) {
        if ( curr_target == targetable ) {
            curr_target = nullptr;
            smallest = TNumericLimits< float >::Max();

    smallest = dot_result;
    curr_target = targetable;

In this code, first, all characters are put into an array, the forward vector of the player is gotten, and smallest, which is used to track the lowest value of the dot product, is set to max float. For each actor in the array, a few checks are made at the beginning to check that it isn't the player or a dead enemy. Once past these checks, the direction vector between the current actor and the player is found and normalized to prepare it for the dot product.

The result of the dot product, if the player was looking directly at the actor, would be one. To simplify finding the actor the player is looking at I chose to subtract the result of the dot product by one, centering the values around zero instead of one, and afterward taking the absolute value. With this process the dot product result of the actor the player is looking directly at will be zero and the result from all other actors will be equal to or greater than zero. Having these values also simplifies the check for making sure the value is less than a specific range, which stops the player from teleporting to an enemy they aren't able to see.


Those two areas cover most of what goes into making this attack, with primarily just animations and a call to set the player's position location left out.

5 views0 comments

Recent Posts

See All


Rated 0 out of 5 stars.
No ratings yet

Add a rating
Post: Blog2 Post
bottom of page