Tag

fundamentals

Unreal Engine C++ Fundamentals – Using Tags with Transformations !

By | Development, Tutorial, Unreal | No Comments

Hey guys,

Today we resume our C++ Fundamentals lessons by looking at interfaces and how they can help simply our life by allowing for common contracts to be shared by different game actors.

As usual you can find the start project on our GitHub page.

What are these tags ? And why do I care ?

Tags are essentially a collection of strings that can be applied to an Actor or an Actors Component and then referenced by other Actors or parts of the game world by those tags.

Very similar to using tags on a blog to include metadata for search engines to query … like this blog !

Tags ?! We don’t need to no stinking tags !

Sure you do, and they are really easy to use which is why this post is going to be super short.

Take a look, in this case we are displaying all tags for a specific actor.

// iterate over all of our actors
for(TActorIterator<AActor> ActorIterator(GetWorld()); ActorIterator; ++ActorIterator)
{
  AActor* Actor = *ActorIterator;
  // ensure actor is not null
  // ignore self if found
  // ensure we find actors of a specific interface only
  if(Actor && Actor != this && Actor->GetClass()->ImplementsInterface(UInteractiveActor::StaticClass()))
  {
    // display all available tags for an actor
    for(FName Tag : Actor->Tags)
    {
     	GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Cyan, Tag.ToString());
    }
  }
}

We can also just check for a specific tag without iterating over all of them by using ActorHasTag method.

if(Actor->ActorHasTag(TagToCheck))
{
    IInteractiveActor::Execute_Interact(Actor);		
}

Wait you forgot about lerping ? What is lerping !?

Lerping is a way of translating between vector A and vector B over some period of time.

For example if you need to scale an object from one size to another you can use FMath::Lerp to accomplish this.

BaseMesh->SetWorldScale3D(FMath::Lerp(BaseMesh->GetComponentScale(), FVector(2.f, 2.f, 2.f), 0.05f));

In this example we go from vector A ( GetComponentScale() of our mesh ) to vector B ( 2x the size ) over a period of time represented by 0.05f time.

Take a look.

That’s it folks, not much more reading but here are a few links for you to check out:

Unreal Engine C++ Fundamentals – Interfaces!

By | Development, Tutorial, Unreal | 3 Comments

Hey guys,

Today we resume our C++ Fundamentals lessons by looking at interfaces and how they can help simply our life by allowing for common contracts to be shared by different game actors.

As usual you can find the start project on our GitHub page.

What is an interface ? Tell me !

An interface is an abstract definition of a contract. What this means is an interface defines how our class can be interfaced ( hah ! ) with while keeping the implementation details away.

More than that it allows us to create a common method signature between various disparate objects.

Consider I have an interface that has a method on it called “DoStuff” and I have two objects, Dog and Person, that inherit this interface. When I call Dog->DoStuff he may perform a trick while if I call the same method of Person->DoStuff he may tell me to fuck off and to stop bothering them. But from the point of view of the code interacting with those actors it’s the same behavior.

This allows for a lot of re-use and generic implementations while keeping the details of those implementations specific.

This all seems very abstract, show me code !

So let’s take a look at how an interface class is structured

UINTERFACE(MinimalAPI)
class UInteractiveActor : public UInterface
{
  GENERATED_BODY()
};

/**
 * 
 */
class UE4FUNDAMENTALS09_API IInteractiveActor
{
  GENERATED_BODY()

  // Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:

  UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Interact")
  void Interact();
};

As you can see it’s pretty thin in definition, we simply have a class that inherits from UInterface and then defines the method signature of “Interact”.

Excellent now we are cooking with fire, now what ?

Once we have the interface in place we now start including it on our objects. Let’s take a look at our InteractiveProp.

UCLASS()
class UE4FUNDAMENTALS09_API AInteractiveProp : public AActor, public IInteractiveActor
{
  GENERATED_BODY()
  
public:	
  // Sets default values for this actor's properties
  AInteractiveProp();

  UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Interact")
  class UStaticMeshComponent* BaseMesh;

protected:
  // Called when the game starts or when spawned
  virtual void BeginPlay() override;

public:	
  // Called every frame
  virtual void Tick(float DeltaTime) override;

  UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Interact")
  void Interact();	// prototype declaration
  virtual void Interact_Implementation() override;	// actual implementation of our interact method

private:
  bool bIsBig;
};

The major thing to note is that in order to leverage the interface, we modify our class signature to bring in “IInteractiveActor”

class UE4FUNDAMENTALS09_API AInteractiveProp : public AActor, public IInteractiveActor

Then we overwrite the Interact method by first declaring the prototype method signature and then the implementation one. Please note that the “_Implementation” is important and has to be exact for the reflection mechanic in Unreal to process your interface + implementation.

UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category = "Interact")
void Interact();	// prototype declaration
virtual void Interact_Implementation() override;	// actual implementation of our interact method

So that was pretty straight forward, now how do I use these guys ?

To execute interface definitions we have a few ways of going about.

First we need to determine if an object uses an interface and we have two ways of checking that.

  1. Based on the ImplementsInterface check
  2. Using a cast to an interface object

Here is the first example

InteractHit.GetActor()->GetClass()->ImplementsInterface(UInteractiveActor::StaticClass())

And the second one

IInteractiveActor* InteractiveActor = Cast<IInteractiveActor>(InteractHit.GetActor());
if(InteractiveActor)
{
  // do stuff
}

Once you determine if an object has an interface the way you execute a call on that object is by passing it into the interface “Execute_” call.

IInteractiveActor::Execute_Interact(InteractHit.GetActor());

This basically says, for interface InteractiveActor Execute the method Interact and pass in our Actor on which that method will be triggered.

Here is a full code block that does this logic using a line trace fired from the player against an object.

void AUE4Fundamentals09Character::Interact()
{
  FVector Start;
  FVector End;

  FVector PlayerEyesLoc;
  FRotator PlayerEyesRot;

  GetActorEyesViewPoint(PlayerEyesLoc, PlayerEyesRot);

  Start = PlayerEyesLoc;
  End = PlayerEyesLoc + (PlayerEyesRot.Vector() * LineTraceDistance);

  FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, this);

  FHitResult InteractHit = FHitResult(ForceInit);

  bool bIsHit = GetWorld()->LineTraceSingleByChannel(InteractHit, Start, End, ECC_GameTraceChannel3, TraceParams);

  if(bIsHit)
  {
    Log(ELogLevel::WARNING, InteractHit.Actor->GetName());
    // start to end, green, will lines always stay on, depth priority, thickness of line
    DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 5.f, ECC_WorldStatic, 1.f);

    // implements interface
    if(InteractHit.GetActor()->GetClass()->ImplementsInterface(UInteractiveActor::StaticClass()))
    {
      IInteractiveActor::Execute_Interact(InteractHit.GetActor());
    }
  }
}

That’s it folks !

In addition to the video here are a few resources for further reading:

 

Unreal Engine C++ Fundamentals – FTimerHandle & Timers

By | Development, Tutorial, Unreal | No Comments

Hey guys,

We are bouncing back to C++ Fundamentals this time looking at FTimerHandle and  Timers in general by messing around with our props.

Additionally you can always find the sample project on our GitHub page.

Timers ?! What are they ?

Timers allow us to trigger events based on elapsed time in the form of creating asynchronous callbacks to specific function pointers.

Plain English: we light a fuse, let it burn down, something explodes !

How do we make these magical exploding clocks ?

Well let’s take a look at some code as these things are pretty easy to understand.

.h

FTimerHandle TriggerDestroyTimerHandle;

UFUNCTION()
void TriggerDestroy();

.cpp

GetWorld()->GetTimerManager().SetTimer(TriggerDestroyTimerHandle, this, &ADestructibleProp::TriggerDestroy, 5.f, true);

void ADestructibleProp::TriggerDestroy()
{
  // do stuff
}

So as you can see the implementation is pretty easy to understand.

  • We are creating a timer from our Time Manager object.
  • We are then registering this call back to use our Timer Handle.
  • Then we assign a callback method to be triggered at the end of our countdown.
  • Then finally we set that the countdown duration is 5 seconds.

Excellent ! Let’s blow some things up.

Timers can also be used to trigger modifications to specific values every so often. In this case we are going to simulate a fuse that will count down every second before it triggers an event.

First we are going to call the timer as we did previously, except this time we are going to call a new method and have this timer run every second.

.cpp

GetWorld()->GetTimerManager().SetTimer(TriggerDestroyTimerHandle, this, &ADestructibleProp::TriggerCountdownToDestroy, 1.f, true);

Then we add in our count down logic

.h

int32 TriggerCountdown;

UFUNCTION()
void TriggerCountdownToDestroy();

Finally we add in our implementation where we modify our count down variable by subtracting one from it every second.

Additionally we trigger a second timer call to our original method by randomly generating a delay before it gets triggered.

.cpp

void ADestructibleProp::TriggerCountdownToDestroy()
{
  // count down to zero
  if (--TriggerCountdown <= 0) 
  {
    int32 RandomDelay = FMath::RandRange(1, 5);

    GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Orange, "Boom ! with a delay of: " + FString::FromInt(RandomDelay));
    GetWorld()->GetTimerManager().SetTimer(TriggerDestroyTimerHandle, this, &ADestructibleProp::TriggerDestroy, RandomDelay, true);
  }
  else 
  {
    GEngine->AddOnScreenDebugMessage(-1, 3.f, FColor::Orange, "Counting down to explosion: " + FString::FromInt(TriggerCountdown));
  }
}

This allows us to have custom implementations in our timers that perform very specific work.

Pretty cool !

 

Below you can find a few more links with some additional reading material:

Unreal Engine C++ Fundamentals – LineTraceSingleByChannel and friends ( DrawDebugBox, DrawDebugLine, FHitResult and VRandCone )

By | Development, Tutorial, Unreal | 9 Comments

Hey guys,

Back to fundamentals with LineTraceSingleByChannel and a bunch of other little methods that go, oh so well, with line traces.

First thing’s first, what is LineTraceSingleByChannel ?

Trace a ray against the world using a specific channel and return the first blocking hit … straight out of the documentation.

If that is not clear enough perhaps this picture can illustrate roughly what a line trace does. Let’s break it down:

  • So the line trace in our case is the stick
  • The start point of the line trace in the world is the bottom right hand corner where someone is holding it
  • The end or the destination of the line trace is Ned Flanders’s eye.
  • Cool.

Now what can we do with line traces ?

Turns out a bunch of stuff.

We can use them to determine where objects are in space relative to us.

For example, in the picture above, the game creator is sending a line trace from the GetRightVector and GetForwardVector location and based on the collision of those hits.

He can then determine the next move for the tile based character component.

He is also determining if the line trace is interacting with any static meshes and if that occurs he shoots out another line trace now parallel to the characters forward vector whatever the remainder of the length of the trace was.

So, all those games you enjoy playing, that are turn / tile based, can be very easily created using this technique !

 

Let’s take a look at the other example.

Here we can shoot a line trace against a component in order to determine if it can be destroyed.

We are going to do something similar to this example but don’t let my lack of imagination stop you from trying other wacky possibilities.

Ok let’s get to drawing some line traces and stop screwing around

 

A basic line trace needs a few components, let’s take a look at the code below.

float LineTraceDistance = 100.f;

FVector Start;
FVector End;

// get the camera view
FVector CameraLoc = FollowCamera->GetComponentLocation();
FRotator CameraRot = FollowCamera->GetComponentRotation();

Start = CameraLoc;

End = CameraLoc + (CameraRot.Vector() * LineTraceDistance);
  
// additional trace parameters
FCollisionQueryParams TraceParams(FName(TEXT("InteractTrace")), true, NULL);
TraceParams.bTraceComplex = true;
TraceParams.bReturnPhysicalMaterial = true;

//Re-initialize hit info
FHitResult HitDetails = FHitResult(ForceInit);

bool bIsHit = GetWorld()->LineTraceSingleByChannel(
  HitDetails,			// FHitResult object that will be populated with hit info
  Start,			// starting position
  End,				// end position
  ECC_GameTraceChannel3,	// collision channel - 3rd custom one
  TraceParams			// additional trace settings
);

if(bIsHit)
{
  // something was hit
}
else
{
  // we missed
}

Breaking it down we can see that the major parts are the start and end locations of where we want the line trace to travel to and from. We obtain those details from the players camera so, wherever our mouse is looking we will shoot out a line up to 100 units.

We can also see that we are going to use the third custom collision channel we created so whatever those settings connect with will be hit.

In addition we are passing in a few line trace parameters, specifically the following:

bTraceComplex – which tells us to use complex collision on whatever we interact with to provide better precision.

bReturnPhysicalMaterial – which tells us to provide details about the physical material, if one exists on the thing we hit, to come back in our hit result.

Lastly we can see that the result of the hit interaction goes into the FHitResult struct from which we can examine various bits of information about what we hit.

You holdin’ FHitResult ?

There are various bits of data we can get back from each hit result so let’s take a look at a few basic ones

if (bIsHit)
{
    Log(ELogLevel::WARNING, "We hit something");

    Log(ELogLevel::WARNING, HitDetails.Actor->GetName());
    Log(ELogLevel::DEBUG, FString::SanitizeFloat(HitDetails.Distance));
}

In this example we are simply printing out the name of the actor we hit as well as the distance between our point of origin and where the hit connected.

Based on those two details we already can do a bunch of stuff like cast the actor to the correct type and perform operations on him, like causing damage or displaying a menu or playing a sound.

Also based on the distance we can make certain assumptions, if the distance is greater than X perhaps our hit doesn’t generate damage or generates less damage due to distance. Or if the distance is too far we cannot interact with a certain lever in the game.

Lot’s of possibilities.

Great but I can’t see where I am aiming ?

No problem, we can drop in a few debug helpers to get us on our way. Specifically DrawDebugBox and DrawDebugLine which let us visualize in the world which way the line goes as well as where the hit occurs.

Here is the code snippet:

if (bIsHit)
{
  Log(ELogLevel::WARNING, "We hit something");
  // start to end, green, will lines always stay on, depth priority, thickness of line
  DrawDebugLine(GetWorld(), Start, End, FColor::Green, false, 5.f, ECC_WorldStatic, 1.f);

  Log(ELogLevel::WARNING, HitDetails.Actor->GetName());
  Log(ELogLevel::DEBUG, FString::SanitizeFloat(HitDetails.Distance));
  DrawDebugBox(GetWorld(), HitDetails.ImpactPoint, FVector(2.f, 2.f, 2.f), FColor::Blue, false, 5.f, ECC_WorldStatic, 1.f);
}
else
{
  Log(ELogLevel::WARNING, "Nothing was hit");
  // start to end, purple, will lines always stay on, depth priority, thickness of line
  DrawDebugLine(GetWorld(), Start, End, FColor::Purple, false, 5.f, ECC_WorldStatic, 1.f);
}

You can see that when we hit something we draw a green debug line and a debug box at the point of impact.

While when we miss we just draw a purple line all the way to the extend of our line trace.

Not bad, but make something interesting !

Ok fine, calm down ! We will make a shotgun spread using Math..s !

For this we are going to dive into the FMath library specifically VRandCone

// convert the degrees to radians
const float Spread = FMath::DegreesToRadians(LineTraceSpread * 0.5f);

FVector Start;
FVector End;

// convert the degrees to radians
const float Spread = FMath::DegreesToRadians(LineTraceSpread * 0.5f);

// get the camera view
FVector CameraLoc = FollowCamera->GetComponentLocation();
FRotator CameraRot = FollowCamera->GetComponentRotation();

Start = CameraLoc;

// handle spread
End = CameraLoc + FMath::VRandCone(CameraRot.Vector(), Spread, Spread) * LineTraceDistance;

Now with a bit of imagination we can take this bit of logic and turn it into a dangerous weapon, for example:

We build a weapon object of type shotgun

That object contains one to many shells in it’s magazine

When each shell is fired we generate 6 pellets

We then take our logic and loop over it 6 times using the direction of the weapon as our starting line traces and the weapons range as the end.

Boom !

Not something we will look at today but in the near future, I promise !

For more details check out the links below:

Unreal Engine C++ Fundamentals – Structs

By | Development, Tutorial, Unreal | 4 Comments

Today we are going to take a little break from our player character series and go over a few Unreal Engine C++ Fundamentals. This is going to be a new side series of videos / helpful material that should give you insight into various common Unreal data types, functions, macros, etc etc.

We may even dive into some more basic concepts just around c++ and object oriented programming like loops, conditionals and inheritance.

Lots of stuff for us to play with but let’s kick this off with Structs !

 

What is a struct ?

A struct is a data structure made up of other data structures …. yes this all makes sense now ….

If you look closely enough though, you have seen them and most likely worked with them already, perhaps in the form of a FVector aka struct FVectoror a FRotator aka struct FRotator.

 

So why do I care about structs when I have classes ?

Structs allow you to have containers for your object definition without having necessarily carrying the burden of new class definitions and instantiations.

A  class tends to contain a lot more logic, it may carry more data around in it self, it may be used for complex inheritance and it has it’s on constructor / destructor life cycle.

A  struct ends up being much smaller in definition, it tends to carry less data around, it performs less logic and tends not to have various accessors that classes do.

Structs also end up being member variables of a class in order to organize and group certain sets of properties together.

 

Outside of those small differences they are pretty much the same.

Both allow for member variables, both allow for classes or structs to be nested as member variables and they also allow inheritance.

 

What about UCLASSand USTRUCTsince you know … Unreal C++ !?

UCLASSand  USTRUCTare pretty much identical too !

UCLASShave their own initialization life cycle and come with constructors and destructors handled by the garbage collection in Unreal. They also allow for variable definition, method signatures, etc etc.

USTRUCT is pretty much a C++ struct but it comes with member reflection. So you can do things like break the FRotator in your Blueprint. Where as this process is a bit more involved with a UCLASS because of how access to member variables is setup.

POINT OF NOTE:

USTRUCTsare not handled by garbage collection so it’s up to the developer to make sure that USTRUCTsbelong to objects, like UObject for example, that will be picked up and destroyed by Unreals garbage collection.

 

Well if they are so great how do we use them ?

In the realm of C++ a struct is really the same thing as a class, except for a few syntactical differences.

For example structs in C++ default their member variables to public by default while classes have private variables by default.

C++ Struct

struct Character {
    int speed; // speed is public
};

C++ Class

class Character {
    int speed; // speed is private
};

 

Now how about doing the same in Unreal ?

Below is a basic definition of a UCLASSwhere we define the member variable of Running.

// Header
UCLASS()
class YOURMODULE_API APlayerCharacter: public ACharacter
{
  GENERATED_BODY()

public:
  UFUNCTION(BlueprintCallable, Category="Player")
  bool IsRunning();

private:
        bool Running = false;
};



// Source
bool APlayerCharacter::IsRunning()
{
    return Running;
}

 

Now let’s build a USTRUCTthat also implements the Running variable.

Since USTRUCTsdon’t require their own class file definitions we can simply put our struct into any accessible header file. Ideally you put structs in their contextually appropriate classes or in meaningful header files ( example: GameStructs.h ).

So let’s re-write the example above using a USTRUCT.

// Header

//Use USTRUCT(BlueprintType) if you would like to include your Struct in Blueprints
USTRUCT()
struct FPlayerStats
{
  GENERATED_BODY()

  // Use UPROPERTY() to decorate member variables as they allow for easier integration with network replication as well as potential garbage collection processing
  UPROPERTY()
  bool Running;	

  FPlayerStats
  {
     Running = false;
  }
};


UCLASS()
class YOURMODULE_API APlayerCharacter: public ACharacter
{
  GENERATED_BODY()

public:
  UFUNCTION(BlueprintCallable, Category="Player")
  bool IsRunning();

private:
  // member variable of FPlayerStats
  FPlayerStats PlayerStats;
};



// Source
bool APlayerCharacter::IsRunning()
{
    return PlayerStats.Running;
}

As you can see it’s pretty easy to convert properties or parts of properties into Structs.

Here are a few helpful links if you want to do more reading about Structs