Monday, September 26, 2016

Unreal Engine 4 C++ Resources

code, coder, coding



Unreal Engine 4 C++ Resources: Intro

Ah, yes, the rough looking starter projects

I have been using Unreal Engine 4 by Epic Games for almost 3 years now and have really enjoyed developing games in this game engine. I have spent hours looking for good content on applying my C++ skills in Unreal Engine 4.

What I want to share with you right now are some good resources that I have constantly gone back to for references. There are about three categories I would split my findings into for Unreal Engine 4 C++ tutorials and examples. These categories would be the obvious, the popular, and the obscure.

Unreal Engine 4 C++ Resources: The List


The Obvious


Whether it be from the horses mouth or an expert in the field. These are solid choices for learning anything about Unreal Engine 4 C++ coding.

C++ Tutorial on Unreal Engine's YouTube Playlist



This tutorial is great for beginners with Unreal Engine 4's C++ API. It will teach you how to create gameplay code, interact with objects, some simple HUD work, as well as some effects. I watched a few of the videos when I was starting out just to get a jumpstart into C++ with UE4.

The Unreal Engine 4 Wiki


The Wiki is always a good place to stop by when looking to implement some common game components. My very own Quest Framework is posted there as well. There are so many tutorials involving AI, C++, Blueprints, and Building with UE4 that it is an invaluable resource.

The Unreal Engine 4 Forums


This is a decent place to go to get some information about C++ in Unreal Engine 4. You may not always get an answer, but when it comes to the more clear questions and descriptions of what you want, there are some good people that will help you out. Sometimes a staffer will comment as well and really steer you into the right direction.

The Source Code


  • The source code. (You MUST be logged in and a part of Epic Games to view this private repository)
If there is anywhere to go as the definite source (pun intended, I'd be lying if I said it wasn't) to C++ code in UE4, it is the source code. If ever you have any questions in regards to how certian modules work or how something is implemented, this is the place to go to. I use it extensively when writing plugins and editor extensions. It is exceptionally helpful to look at the MessageBus, OnlineSubsystem, and Actor replication portions of the code when writing networked games.

The Popular


Tom Looman's Blog


When it came to writing network code and code for interactive objects in Unreal Engine 4, this was my go to place. Tom Looman has most of his tutorials in C++ and Blueprints. What this does is allow for a smooth transition if you are used to Blueprints and wish to move to C++.

The Unreal Engine 4 Sub-Reddit


Reddit seems to have a large crowd and there is relatively good activity in the subreddit. Most of the time I see a lot of beginners go there to ask questions. It is usually pretty helpful.

Rama / EverNewJoy


This person does a lot of stuff with UE4 and has a Plugin library for Blueprints. There are also a few other Plugins on the marketplace by this person. From forum posts to tutorials, transition guides, and wiki posts - Rama has a lot of content and most of it is in C++. Also, Rama seems to enjoy lots of color and hearts.


The Obscure


This is just a small collection of links to random things about Unreal Engine 4 and it's C++ components that nobody really talks about. Most of these links are one off a very specific. They are as follows:
Things start to look nicer the more you apply yourself
Well, that is about all I use when going in to take a look at C++ demos and examples in Unreal Engine 4. Obviously, this is not the extent of all the resources available for Unreal Engine 4 C++. If there is anything that you may know of that I missed and is usable by a wide range of people, feel free to comment. I hope for anyone who was looking for some help in C++ for Unreal Engine 4 that this offered as a good guidance of where to go.

Until next time! Enjoy your game programming!

Saturday, September 17, 2016

Unreal Engine Quest Framework Part 1.5

After spending some time on vacation and on an epic honeymoon, I have finally had time to get back to continue my original Quest Framework series. But, first, let me interrupt and thank everyone out there for their support. This is by far the most popular content I have ever written and it brings me great joy that you support it and find it useful.

With all the time off, and the time back at my day job, I have not been able to fully complete the second part of my Quest Framework series. However, I do have an addition I would like to share that may be useful. This addition is a new class that generates random Objectives from a predefined list of objectives inside of a Quest.


Quest Framework Part 1.5: Random Objectives


Want your players to look this excited for your quests? Don't use this framework for evil, no randomly generated fetch quests allowed!


Following the format of the last post, I will layout the header file for you, then explain some of the variables. From there I will layout the definitions and explain all of the logic.

The Head


class QUESTGAME_API AQuestRandom : public AQuest
{
    GENERATED_BODY()

public:
    AQuestRandom();

    virtual void BeginPlay() override;
 
protected:
    UPROPERTY(EditDefaultsOnly, Category = "Quest")
         TArray<TSubclassOf<AObjective>> PossibleObjectives;

    UPROPERTY(EditDefaultsOnly, Category = "Quest", meta=(UIMin=1))
         int32 MinObjectivesGenerated;

    UPROPERTY(EditDefaultsOnly, Category = "Quest", meta=(UIMin=1))
        int32 MaxObjectivesGenerated;

private:
    /** Helper methods for validation and generation.
    * ::GenerateRandomObjectives() could be made public 
    * and wrapped with UFUNCTION(BlueprintCallable, Category="Quest") to make it exposed to the rest of your game.
    */
    void GenerateRandomObjectives();
    bool IsValidConfiguration() const; 
 
};

Pretty nifty huh? We just inherit from AQuest (defined in the original Part 1 post) and add a few configuration parameters that can be set in either an inherited class or Blueprint.

PossibleObjectives is the meat of this class. Just add AObjective subclasses to it in the derived Blueprint or subclass and whenever the AQuestRandom is spawned in game, the class will do all the work of adding some random Objectives.

MinObjectivesGenerated and MaxObjectivesGenerated are there to help add some constraints to the amount of randomly generated quests. In proper fashion, these numbers are just constraints on the random determination of the amount of random Objectives created. I heard people like randomness on top of their randomness so I threw it in just for fun.

Next, I will show you the source for this nifty class and explain the true meat of the randomization algorithm (which isn't too difficult at all).



The Source


Free stock photo of technology, computer, desktop, programming

#include "QuestRandom.h"

AQuestRandom::AQuestRandom() :
    AQuest(),
    MinObjectivesGenerated(AbsoluteMin),
    MaxObjectivesGenerated(AbsoluteMin)
{

}

void AQuestRandom::BeginPlay()
{
    if (IsValidConfiguration())
    {
        GenerateRandomObjectives();
    }
    //Must be called last as we need to fill the Objective subclass array first
    Super::BeginPlay(); 
}

void AQuestRandom::GenerateRandomObjectives()
{
    const bool bMakeOnlyOne = MinObjectivesGenerated == MaxObjectivesGenerated;
    if (bMakeOnlyOne)
    {
        int32 RandomIndex = FMath::RandRange(0, PossibleObjectives.Num() - 1);
        Objectives.Add(PossibleObjectives[RandomIndex]);
    }
    else
    {
        int32 RandomCount = FMath::RandRange(MinObjectivesGenerated, MaxObjectivesGenerated);
        for (int32 i = (AbsoluteMin - 1); i < RandomCount; ++i) 
        {
            int32 RandomIndex = FMath::RandRange(0, PossibleObjectives.Num() - 1);
            /* Note: if you want only one type of quest to be active at a time,
            * i.e. treat Objective types array as a set, use AddUnique
            */
            Objectives.Add(PossibleObjectives[RandomIndex]);
        }
    }
}

bool AQuestRandom::IsValidConfiguration() const
{
    return MinObjectivesGenerated <= MaxObjectivesGenerated && PossibleObjectives.Num() > 0;
}

Awesome right? We really only need one function to add randomly generated Objectives to our Quests! Huzzah! So, let us look immediately into the GenerateRandomObjectives function as it is the crux of our class.

First, if we have the same MinObjectivesGenerated and MaxObjectivesGenerated, we are going to short circuit and say the designer only wants to pick one random Objective for this Quest. It is also the default behavior due to the values set in the Constructor of the class.

If the designer does not go with this default behavior we will actually do some work.

So, if we really look at it, the algorithm is not that hard to implement. All we need is to grab a random number clamped to the values provided to us from MinObjectivesGenerated and MaxObjectivesGenerated. From there we just iterate as many times as the RandomCount has defined to create that many Objectives.

In both configurations we just grab a random number starting at 0 (the starting index of an array) and PossibleObjectives.Num() - 1 (we subtract one to ensure we are within the bounds of the array as index access is 0 based but the Num() starts at 1 - this is a general rule).

From there, the base class takes care of everything else for us.

The End


And there you have it. Random objective generation. So, hopefully you can add some more content and unique playthroughs of your games via random Objectives in your Quests.

Until next time!

Note - I will have an official part 2 for this series that will have subsections. I am currently prototyping with the idea of implementing quests as state machines and message publishers to decouple a lot of the quest implementation from your actual game-play code. On top of that I am going to implement it as a plugin with components so that you can port it over multiple games. Why? Because 'Quests', 'Objectives', and 'Missions' are really all the same thing and can be written generic enough that the core foundation of them work across all game types.

Thursday, February 25, 2016

Unreal Engine 4 Quest Framework C++ Part 1

Lately, I have been working on a simple horror game in UE4 that has a very simple Objective system that drives the gameplay. After looking at the code, I realized it could serve as the basis of a framework for a generic questing system. Today I will share all of that code and explain each class as it pertains to the framework.

The following classes to get started on a simple quest framework would are AQuest and AObjective, using the UE4 naming conventions for classes. AObjective is metadata about the quest as well the actual worker when it comes to completing parts of a quest. AQuest is a container of objectives and does group management of objectives. Both classes are derived from AInfo as they are purely classes of information and do not need to have a transform or collision within the world.

Objectives

Since it is the foundation for a quest, I will first layout and explain AObjective. The header of AObjective goes as follows:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Info.h"
#include "Objective.generated.h"

UCLASS()
class QUESTGAME_API AObjective : public AInfo
{
    GENERATED_BODY()
 
public: 
    // Sets default values for this actor's properties
    AObjective();

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
 
    // Called every frame
    virtual void Tick( float DeltaSeconds ) override;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "O" )
        FText Description;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "O" )
        FName ObjectiveName;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "O" )
        bool MustBeCompletedToAdvance;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "O" )
        int32 TotalProgressNeeded;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "O" )
        int32 CurrentProgress;

    UFUNCTION( BlueprintCallable, Category = "O" )
        void Update( int32 Progress );
    UFUNCTION( BlueprintCallable, Category = "O" )
        virtual bool IsComplete( ) const;
    
    UFUNCTION( BlueprintCallable, Category = "O" )
        virtual float GetProgress( ) const;

 
 
};

Not that bad of a deal. The only responsibilities of an AObjective is to track the completion of the sub-portion of an AQuest and offer some idea of what the player must do.

The objective is tracked by the CurrentProgress and TotalProgressNeeded properties. Added by the supplied helper functions, Update, IsComplete, and GetProgress, we can get a reasonable amount of data about just this tiny portion of a quest. These functions give you all the functionality needed to start a questing framework for your UE4 game.

There is one boolean property that has not been mentioned: MustBeCompletedToAdvance. Depending on the use case, this could be used to ensure a sequential order in objectives or having required and optional objectives. I will implement it as the first in this tutorial. Only minor changes later on would be needed to use it as an indicator or optional or required quests. Or, you could just add a new property to support both.

There are two more properties that help us out with AObjective management: ObjectiveName and Description. ObjectiveName can be thought of as a unique identifier for the implemented AObjective. The ObjectiveName's purpose is for player feedback. For instance, the FText value could be (in simple string terms) "Get a rock". It is nothing specific to the game, it is only something to be used as a hint in either a UI or other visual element to let the player know that they need to do something in order to complete the objective.

Next, we can look at the small amount of code that is used to define AObjective.

// Fill out your copyright notice in the Description page of Project Settings.

#include "QuestGame.h"
#include "Objective.h"


// Sets default values
AObjective::AObjective( ) :
    Description( ),
    ObjectiveName( NAME_None ),
    TotalProgressNeeded( 1 ),
    CurrentProgress( 0 ),
    MustBeCompletedToAdvance( true )
{
  // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AObjective::BeginPlay()
{
    Super::BeginPlay();
}

// Called every frame
void AObjective::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

}

void AObjective::Update( int32 Progress )
{
    CurrentProgress += Progress;
}

bool AObjective::IsComplete( ) const
{
    return CurrentProgress >= TotalProgressNeeded;
}

float AObjective::GetProgress( ) const
{
    check( TotalProgressNeeded != 0 )
    return (float)CurrentProgress / (float)TotalProgressNeeded;
}

Again, you will be hard pressed to say "that is a lot of code". Indeed, the most complex code is the division in the GetProgress function.

Wait, why do we call / override BeginPlay or Tick? Well, that is an extreme implementation detail. For instance, what if, while an AObjective is active, you want to tick a countdown for a time trialed AObjective.

For BeingPlay we could implement various other details such as activating certain items in the world, spawning enemies, and so on and so forth. You are only limited by your code skills and imagination.

Right, so how do we manage all of these objectives and make sure only relevant AObjectives are available? Well, we implement an AQuest class in which it acts as an AObjective manager.

Quests

Here is the declaration of an AQuest to get you started:


// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameFramework/Info.h"
#include "Quest.generated.h"

UCLASS()
class QUESTGAME_API AQuest : public AInfo
{
    GENERATED_BODY()
 
public: 
    // Sets default values for this actor's properties
    AQuest();

    // Called when the game starts or when spawned
    virtual void BeginPlay() override;
 
    // Called every frame
    virtual void Tick( float DeltaSeconds ) override;

public:
   UPROPERTY( EditDefaultsOnly, BlueprintReadWrite, Category = "Q" )
        TArray<class AObjective*> CurrentObjectives;

    UPROPERTY( EditDefaultsOnly, BlueprintReadWrite, Category = "Q" )
        TArray<TSubclassOf<AObjective>> Objectives;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "Q" )
        USoundCue* QuestStartSoundCue;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "Q" )
        FName QuestName;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "Q" )
        FText QuestStartDescription;

    UPROPERTY( EditDefaultsOnly, BlueprintReadOnly, Category = "Q" )
        FText QuestEndDescription;

    UFUNCTION( BlueprintCallable, Category = "Q" )
        bool IsQuestComplete( ) const;

    UFUNCTION( BlueprintCallable, Category = "Q" )
        bool CanUpdate( FName Objective );

    UFUNCTION( BlueprintCallable, Category = "Q" )
        void Update( FName Objective, int32 Progress );

    UFUNCTION( BlueprintCallable, Category = "Q" )
        bool TryUpdate( FName Objective, int32 Progress );

    UFUNCTION( BlueprintCallable, Category = "Q" )
        float QuestCompletion( ) const; 
 
};

Not much bigger that the AObjective class is it? This is because all AQuest does is wrap around a collection of  AObjective's and provides some utility functions to help manage them.

The Objectives property is a simple way to configure an AQuest's objectives via the Blueprints Editor. And the CurrentObjectives is a collection of all live AObjective's that are configured for the given AQuest.

There are several user friendly properties such as a USoundCue, FName, and FText types that help give audio visual feedback to the player. For instance, when a player starts a quest, a nice sound plays - like a chime - and the QuestStartDescription text is written to the player's HUD and a journal implementation. Then, when a player completes a quest, a get is called for the QuestEndDescription property and writes it to a journal implementation. But those are all specific implementation details related to your game and is limited only by coding skills and imagination.

All of the functions for AQuest are wrappers to operate on collections of AObjectives to update and query for completion. All AObjectives in the AQuest are referenced and found by FName property types. This allows for updating different instances of AObjectives that are essentially the same, but differ at the data level. It also allows the removal of managing pointers. As another argument, it decouples knowledge of what an AObjective object is from other classes, so completing quests via other class implementations only requires the knowledge of an AQuest - or the container for the AQuest - object and default types supplied by the engine such as int32 and FName.

How does this all work, well, just like before, here is the definition of AQuest:

// Fill out your copyright notice in the Description page of Project Settings.

#include "QuestGame.h"
#include "Objective.h"
#include "Quest.h"


AQuest::AQuest() :
    QuestName( NAME_None ),
    CurrentObjectives( ),
    QuestStartDescription( ),
    QuestEndDescription( )
{
}

void AQuest::BeginPlay()
{
    Super::BeginPlay();
    UWorld* World = GetWorld();
    if ( World )
    {
        for ( auto Objective : Objectives )
        {
            CurrentObjectives.Add(World->SpawnActor(Objective));
        }
    }
}

// Called every frame
void AQuest::Tick( float DeltaTime )
{
    Super::Tick( DeltaTime );

}

bool AQuest::IsQuestComplete() const
{
    bool result = true;
    for ( auto Objective : CurrentObjectives )
    {
        result &= Objective->IsComplete();
    }
    return result;
}

bool AQuest::CanUpdate( FName Objective )
{
    bool PreviousIsComplete = true;
    for ( auto Obj : CurrentObjectives )
    {
        if ( PreviousIsComplete )
        {
            if ( Objective == Obj->ObjectiveName )
               return true;
            else
               PreviousIsComplete = Obj->IsComplete() |
               !Obj->MustBeCompletedToAdvance;
        }
        else
        {
            return false;
        }
    }
    return true;
}

void AQuest::Update( FName Objective, int32 Progress )
{
    for ( auto Obj : CurrentObjectives )
    {
        if ( Obj->ObjectiveName == Objective )
        {
            Obj->Update( Progress );
            return;
        }
    }
}

bool AQuest::TryUpdate( FName Objective, int32 Progress )
{
    bool result = CanUpdate( Objective );
    if ( result )
    {
        Update( Objective, Progress );
    }
    return result;
}

float AQuest::QuestCompletion( ) const 
{
    int32 NumObjectives = CurrentObjectives.Num( );
    if( NumObjectives == 0 ) return 1.0f;

    float AggregateCompletion = 0.0f;
    for( auto Objective : CurrentObjectives )
    {
            AggregateCompletion += Objective->GetProgress( );
    }
    return AggregateCompletion / (float)NumObjectives;
}


Probably the most complex code out of all of this is the CanUpdate method. It checks to see, sequentially (so order of AObjective configuration matters), if an AObjective is completed and if it is required to complete any other AObjectives after it. This is where the bitwise OR comes in. So basicly, we cannot advance to the requested AObjective if any of the previous AObjectives are not complete and are set to MustBeCompletedToAdvance (or as the listeral code says you CAN advance if the previous AObjective IS complete OR it does not required to be completed in order to advance).

The IsComplete function is just and aggregate check to see if all AObjectives are complete - defining a completed AQuest. The QuestCompletion method is a simple averaging of all AObjective completion percentages.

Also, the AQuest class has a simple function to wrap up the CanUpdate and Update calls into one neat little function called TryUpdate. This allows a check for the ability to update before applying the requested progress update and returns an indicator of success or failure. This is useful when code outside of AQuest wants to attempt AObjective updates without caring about much else.

Finally, for the same reason of AObjective's BeginPlay and Tick functions, AQuest also overrides these to allow your coding skills and imagination to fly.

Hopefully, this was a good introduction into the groundwork of designing a questing framework for your Unreal Engine 4 game. If you did enjoy it, comment or like it. If there is enough interest I will continue on-wards with Part II: Nesting Quests and Objectives. That part will be a tutorial just like this, with full code samples, explaining how to structure the framework to nest multiple AObjectives into an AObjective to create a structure of sub-objectives as well as the same pattern applied to AQuest to supply sub-quests.