Announcement

Collapse
No announcement yet.

C++ Getting Startet: Mashup

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    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.

    Code:
    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)
    		/**
    		* 
    		*
    		* [MENTION=209895]param[/MENTION] material			Material that is used for the RuntimeMesh.
    		* [MENTION=209895]param[/MENTION] colors				VertexColor of the RuntimeMesh data. Need to be the same length as vertices.
    		* [MENTION=209895]param[/MENTION] vertexLength			ArrayLength for all arrays that correspond to the supplied Vertex array.
    		* [MENTION=209895]param[/MENTION] triangles			Triangle data of the RuntimeMesh data.
    		* [MENTION=209895]param[/MENTION] 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...nts/index.html
    	https://docs.unrealengine.com/latest...nes/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-...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...ays/index.html
    https://www.unrealengine.com/blog/op...or-performance
    ______________
    Measure code Execution time
    	http://stackoverflow.com/questions/2...-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.
    	*	
    	* [MENTION=82295]r[/MENTION]eturn 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...tringHandling/
    ______________
    UINTERFACE
    
    UINTERFACE implementation depends on how you declare the Interface
    To get an Blueprintable Interface, see: 
    	https://www.youtube.com/watch?v=6RmP...TSZ45wLK2R3B-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
    Last edited by Rumbleball; 11-03-2016, 08:52 AM.
    NodePrefabs | PluginBuilder | NotificationBackbone | WidgetBox | RuntimeMeshImportExport | DebugWidget | SteamWorkshopAccessor

    #2
    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.

    Comment


      #3
      Originally posted by Kufi-Smacker View Post
      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.
      NodePrefabs | PluginBuilder | NotificationBackbone | WidgetBox | RuntimeMeshImportExport | DebugWidget | SteamWorkshopAccessor

      Comment


        #4
        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.

        Originally posted by Rumbleball View Post
        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.

        Comment


          #5
          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.

          Originally posted by Rumbleball View Post
          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.

          Comment


            #6
            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.

            Originally posted by Rumbleball View Post
            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.

            Comment


              #7
              Thanks for this mashup. I'm also beginner in Unreal and I found this useful.
              bartlomiejwolk.wordpress.com

              Comment

              Working...
              X