Download

C++ Getting Startet: Mashup

Hey guys.
Developing with Unreal for three Month now. Spend one of that for getting startet with Unreal C++.
As this engine lives by its community and there are so much tutorials (special thanks to Rama) to get it startet, I want to share with you as well.
The one month into C++ I noted some stuff that I came across what was not really obvious to me, as well as some usefull links. There is a bit of code as well.
Its not really structured and more of a informational mashup instead of a tutorial.

If you have any suggestions on some points, feels free to discuss or contribute. I will try to update the information from time to time.


Virtual Studio uses Intellisense for autocomplete. Intellisense is horribly slow for large projects. Unreal Community and Developers tell you to use "Visual Assist": http://www.wholetomato.com/
______________
If Compile Times are very high, you migh try this: https://answers.unrealengine.com/questions/3647/how-to-improve-compile-times-for-a-c-project.html
______________
Within the file YourProjectName.build.cs you need to make your project aware of the files pathes you need to use. Each IDE can only #include files that are known. By default Unreal projects don´t know all available files. To let Unreal know what files you want to use, you need to use the following:
	PublicDependencyModuleNames.AddRange(new string] { "RuntimeMeshComponent", ".." });
This line accepts the names of Modules. Modules are folders within the Engine folder structure. By default some modules are already included. The default Modules are in ..\Sources\Runtime\
Files within Folders in one of these included modules (Engine/Classes/Materials/Material.h) can be included with '#include "Materials/Material.h"'
______________
Important keyboard shortcuts when using Visual Studio 2015 (Community Edition)

CTRL+K,CTRL+O = switch between header and source 
CTRL+C -> CTRL+V = does copy a line and pasts it in the line beneath if nothing is highlighted.
CTRL+ArrowKeys = Screen scroll
CTRL+L = cut line
CTRL+SHIFT+L = delete line
ALT+UP = Move line up
ALT+DOWN = Move line down
_______________
Some answers to first questions comming up when looking at a class.
	https://answers.unrealengine.com/questions/1728/ue4-beginner-c-questions.html

Also have a look in the Documentation: https://docs.unrealengine.com/latest/INT/Programming/index.html

There are example projects you can use to look stuff up. Just look around the forum or google.
_______________
Unreal Engine makes excessive use of macros, for core macros see ObjectBase.h. For some macros there are namespaces that consist of parameter for the corresponding macro.

MACRO : NAMESPACE
UPROPERTY : UP
USTRUCT : US
UFUNCTION : UF
UCLASS : UC
UINTERFACE : UI
UPARAM : ?
ENUM : ?
UDELEGATE : ?

there is also a namespace UM that consists of meta data keywords for the above macros. Look at the namespace specifically if something is needed.

IMPORTANT: When using these namespaces to get macro parameter, delete the Namespaces afterwards. UClass(UC::BlueprintType) will lead to errors. Corrent: UClass(BlueprintType)
_______________
Variables that are defined as UPROPERTY are garbage collected. If not defined as UPROPERTY keep in mind to "delete" assigned pointers (free the reserved memory).
_______________
Unreal Engine uses "Super" keyword to call the parent of a class. "Super" is not C++ standard and of the Forum: it is a typedef from the Engine Code.
_______________
C++ does support multiple inheritance, but Unreal Code does, at least in some situations, prevent it (not interface)
	https://answers.unrealengine.com/questions/101638/multiple-inheritance-not-working-with-uclass.html
_______________
Text literals ("text") should always be surrounded with TEXT() macro. The macro does provide a greater variety of characters, as "text" would be ANSI format. E.g. TEXT("Hello Sir")
_______________
UFUNCTION()

UFUNCTION() MUST have something within the brackets! E.g. UFUNCTION(BlueprintCallable, Category = "Misc") . If not, there will be compiler errors. "Category" is a must have keyword.
To declare an output parameter you would need to use a referenz "type& name". E.g. void getNumber(int32& numberOfDay)
To declare an input that is "call by referenz" you would need to use "const" -> "const type& name". E.g. void setSomething(const int32& number)
To declare an input that is Pass-By-Referenz and is read/write use UPARAM(ref). E.g. void changeThisToWhatEver(UPARAM(ref) int32& value)
	To clarify: Changing this parameter within the function, the parameter passed into the function will be changed as well. (It is actually the same)
Blueprints float = c++ float (there is no double in blueprints)
Blueprints integer = c++ int32 (ONLY int32, not larger or smaller. "Unsigned" is not supported as well)
UFUNCTION(BlueprintPure, ...): BlueprintPure hides the execution pin for the Blueprint node. The function can change members of the class. Can be used for getters (not recommended, see below. Use const functions)
	As of own guessing: A BlueprintPure function will only be called when a return value is needed. Means it may be there is changes to members at points where it is not expected.
		As of this: DON'T USE BlueprintPure IF THERE IS NO NEED TO!
Const functions: "int32 getStuff() const"; can NOT be used with UFUNCTION(BlueprintPure, ...). These functions have no execution pin in their Blueprint node. These functions cannot change member variables, except "mutable" members.
	Const functions are recommended over UFUNCTION(BlueprintPure, ...)

IMPORTANT: If a function is declared to be a UFUNCTION() there MUST be a definition in order to compile. Otherwise unreadable linkerrors will appear during compile.

Working code: (dont forget to create a definition)
		/**
		* 
		*
		* @param material			Material that is used for the RuntimeMesh.
		* @param colors				VertexColor of the RuntimeMesh data. Need to be the same length as vertices.
		* @param vertexLength			ArrayLength for all arrays that correspond to the supplied Vertex array.
		* @param triangles			Triangle data of the RuntimeMesh data.
		* @param triangleLength			ArrayLength of the Triangle array.
		*/
		UFUNCTION(BlueprintCallable, Category = "MergeCore")
		FSMergeCoreObjectData MergeCore_Insert(
			const UMaterialInterface* material,
			const TArray<FLinearColor>& colors,
			const int32& vertexLength,
			const TArray<int32>& triangles,
			const int32& triangleLength
		);
	
Also see:
	https://docs.unrealengine.com/latest/INT/Engine/Blueprints/TechnicalGuide/ExtendingBlueprints/index.html
	https://docs.unrealengine.com/latest/INT/Engine/Blueprints/TechnicalGuide/Guidelines/index.html
_______________
USTRUCT

To create Make/Break nodes for Blueprint, each property of the struct what shall be visible in Make/Break node needs UPROPERTY(BlueprintReadWrite).
If a Blueprint variable is of that struct type, you need UPROPERTY(EditAnywhere) to set the default values, otherwise the properties are not shown and defaults can´t be set.
USTRUCT can not be created within UCLASS. It can be in the same file, but not in the body of each other.

Working code with automatic Make/Break nodes in Unreal:
		
		USTRUCT(BlueprintType)
		struct FSMergeCoreObjectData
		{
			GENERATED_BODY()

			// section used to save an Object
			UPROPERTY(BlueprintReadWrite, EditAnywhere)
			int32 saveSection;
		};
_______________
Multi-Threading

https://wiki.unrealengine.com/Multi-Threading:_How_to_Create_Threads_in_UE4

Does a thread influence the GameThread to much (e.g. GEngine->AddOnScreenDebugMessage(..)), the game will crash.
_______________
Comparefunctions are found in ../Sources/Runtime/Engine/Kismet/KismetMathLibrary.h
	access with: UKismetMathLibrary::equalequal_...
_______________
Functions named K2... are Blueprint exposed functions. K2 refers to Kismet2. They renamed it to Blueprint in the Editor, but kept the name in C++.
These functions are not restricted to Blueprint and can be used in C++ as well.
_______________
Some functions, especially functions that work with UObject, want you to declare an "Outer". "Outer" means simply the owner of the Object, e.g. Level, Actor, ...
_______________
TArray<...>

TArray is a dynamic Array type, that allocates new memory if needed. To prevent the Array from allocating new memory with every new entry, TArray allocates 'Slack' with the newly inserted item, if the TArray needed to be reallocated because it was full. 'Slack' is empty Storage at the end of the Array and scales dynamically, depending on the allocator of the TArray (there is a default).
However, a TArray of a Struct that contains TArrays will behave somewhat different. The TArray in the struct will not scale dynamically!
When inserting 'empty' space manually, and you are sure you will overwriting that space anyway, use AddUninitialized()/InsertUninitialized(). Will save time on creation of that space.
	Not sure how Num() and Max() will behave, not testet
To initialize a TArray with Slack, use Reserve()
	E.g. TArray<int32> test; test.Reserve(100);
		test.Num() will return 0.
		test.Max() will return 100.
		test.GetSlack() will return 100.

https://en.wikipedia.org/wiki/Dynamic_array
https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/TArrays/index.html
https://www.unrealengine.com/blog/optimizing-tarray-usage-for-performance
______________
Measure code Execution time
	http://stackoverflow.com/questions/22387586/measuring-execution-time-of-a-function-in-c

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

#pragma once

#include "YourProject.h"
#include <chrono>

class YOURPROJECT_API DebugHelper
{
private:
	DebugHelper();
	~DebugHelper();
public:

	/**	Start Timer. There is only 1 that will be overwritten when calling again,
	 *	Call StopTimer() to stop the timer.
	 *	Call GetTimerDuration() for the time needed.
	 *	Make sure to not use this functions in parallel threads. Only for Debug
	 **/
	static void StartTimer();

	/**	Stop Timer. There is only 1 that will be overwritten when calling again,
	*	Call StartTimer() to start the timer.
	*	Call GetTimerDuration() for the time needed.
	*	Make sure to not use this functions in parallel threads. Only for Debug
	**/
	static void StopTimer();
	
	/**	Get the Timer duration.
	*	Call StartTimer() to start the timer.
	*	Call StopTimer() to stop the timer.
	*	
	* @return Returns the Time between StartTimer() and StopTimer()
	**/
	static FString GetTimerDuration();


	
private:

	// start time for the time measurement
	static std::chrono::high_resolution_clock::time_point DebugHelper::timeStart;
	// end time for the time measurement
	static std::chrono::high_resolution_clock::time_point DebugHelper::timeEnd;
};

################################# .cpp #####################################
#include "YourProject.h"
#include "DebugHelper.h"
#include <sstream>

DebugHelper::DebugHelper()
{
}

DebugHelper::~DebugHelper()
{
}


 std::chrono::high_resolution_clock::time_point DebugHelper::timeStart;
 std::chrono::high_resolution_clock::time_point DebugHelper::timeEnd;

void DebugHelper::StartTimer()
{
	timeStart = std::chrono::high_resolution_clock::now();
}

void DebugHelper::StopTimer()
{
	timeEnd = std::chrono::high_resolution_clock::now();
}

FString DebugHelper::GetTimerDuration()
{
	std::stringstream buffer;
	buffer << std::chrono::duration_cast<std::chrono::microseconds>(timeEnd - timeStart).count();
	return  FString(buffer.str().c_str());
}


______________
Conversion from String to FString, other way round and more stuff
	https://docs.unrealengine.com/latest/INT/Programming/UnrealArchitecture/StringHandling/
______________
UINTERFACE

UINTERFACE implementation depends on how you declare the Interface
To get an Blueprintable Interface, see: 
	https://www.youtube.com/watch?v=6RmPHW8MfP4&list=PL5FKAcgXGa8RoR6oboATSZ45wLK2R3B-g
	https://wiki.unrealengine.com/Interfaces_in_C%2B%2B


It is also possible to declare an UInterface that is not implementet in Blueprint. The syntax changes a lot:

#####################  Interface .h      ########################
#pragma once

#include "UndoRedoItem.generated.h"

// This class does not need to be modified.
UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UUndoRedoItem : public UInterface
{
	GENERATED_UINTERFACE_BODY()
};

class IUndoRedoItem
{
	GENERATED_IINTERFACE_BODY()

	// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
	
	// don´t do for Interfaces if that interface shall be implementable in Blueprint:
	// VIRTUAL ... = 0
	// This means Pure Virtual and means: must be implemented.
	// Blueprint/Unreal does not like that

	// Called when stuff is undone
	UFUNCTION()
	virtual void Undo() = 0;
};

#####################    Interface .cpp      ########################
#include "YourProject.h"
#include "UndoRedoItem.h"


// This function does not need to be modified.
UUndoRedoItem::UUndoRedoItem(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}

// Add default functionality here for any IUndoRedoItem functions that are not pure virtual.


#####################    Implementing Class .h      ########################
#pragma once

#include "UndoRedoHistory/UndoRedoItem.h"
#include "UndoRedo_SpawnActor.generated.h"

UCLASS()
class YourProject_API UUndoRedo_SpawnActor: public UObject, public IUndoRedoItem
{
	GENERATED_BODY()

public:
	...

	virtual void Undo() override;
}


#####################    Implementing Class .cpp      ########################
#include "YourProject.h"
#include "UndoRedo_SpawnActor.h"

...

void UUndoRedo_SpawnActor::Undo()
{

}

______________




regards Rumbleball

I have to say for me starting up, all that stuff is Giberish really. If you truly care about games you should take college courses. and know software engineering to go through the a.p.i. Imagaine you have to fix errors or something copying someones code won’t help.

Thanks for your feedback. As mentioned, it´s only a mashup. A college course about game programming might not get you startet with Unreal. And there is no code to fix an error, just sample code to give hints.

I don’t mean to down you at all, and you’ll probably do great with what your doing. But to really be able to do this you need to know more then just a language. I know c++ but I know nothing about compilers,how to optimize code, A little about safe coding. Everything thing from call backs and etc. that low level stuff you really need to know. You won’t even be able to read the c++ A.P.I that takes software engineering skills. Which isn’t so hard. Since it’s worded in proper coding standard terms. None the less best of luck to you.

I don’t mean to down you at all, and you’ll probably do great with what your doing. But to really be able to do this you need to know more then just a language. I know c++ but I know nothing about compilers,how to optimize code, A little about safe coding. Everything thing from call backs and etc. that low level stuff you really need to know. You won’t even be able to read the c++ A.P.I that takes software engineering skills. Which isn’t so hard. Since it’s worded in proper coding standard terms. None the less best of luck to you. As of me I’m a hardcore gamer and car about my product. You’ll do just fine most likely.

Also depends on what college you go to a good college tells you everything. Even who to make your own compiler. Where as you’ll know everything within unreal engine automatically.

Thanks for this mashup. I’m also beginner in Unreal and I found this useful.