Programming blog

Unreal


Table of Contents

    Debugging

    Disabling optimization of c++ files

    To enable automatic disabling of optimizations, edit BuildConfiguration.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <BuildConfiguration>
            <bAdaptiveUnityDisablesOptimizations>true</bAdaptiveUnityDisablesOptimizations>
        </BuildConfiguration>
    </Configuration>

    This will disable optimization for all files that are checked out in perforce.

    More info here: https://dev.epicgames.com/community/learning/tutorials/dXl5/advanced-debugging-in-unreal-engine

    UObject debugger object descriptions

    It is easier to use Debugger uses UObject->GetName(). So if you will Rename() UObject, then debugger will conveniently show this nice name to you.

    Non UObject debugger object descriptions

    If you want nice debugger info about an object that is not a UObject and you can’t Rename this object, then you can use natvis file to override how debugger prints this object.

    natvis location

    1. For game types: Open <Engine>Extras\VisualStudioDebugging\Unreal.natvis file and add entry for your object. This will work in Rider debugger. I am adding entry for my FMyObject
    2. For plugin types: create a new file: <plugin name>/Source/<your module name><module name>.natvis

    <?xml version="1.0" encoding="utf-8"?>
    <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
    
    <Type Name="FMyObject">
       <DisplayString>(Table={DataTableName} Row={RowName})</DisplayString>
     </Type>
    
    </AutoVisualizer>

    Where DataTableName and RowName are FName types in a struct.

    More info here:

    Printing value of enum

    To print a human readable value of an enum, it must be marked as UENUM(). Example

    UENUM()
    enum class EOptions
    {
    	Option1,
    	Option2,
    	Option3
    };
    EOptions SelectedOption = EOptions::Option1
    
    UE_LOGFMT(LogTemp, Log, "Current option is {Options}", UEnum::GetValueAsName(SelectedOption));
    
    //this will print "Current option is Option1"

    To print the display name of an UEnum:

    UENUM()
    enum class ECreatureType
    {
    	IsRobot UMETA(DisplayName = "Is a robot"),
    	IsHuman UMETA(DisplayName = "Is a human")
    };
    const ECreatureType CreatureType = ECreatureType::IsRobot;
    
    FString::Format(TEXT("This creature type is a {0}"), StaticEnum<ECreatureType>()->GetDisplayNameTextByValue(static_cast<int64>(CreatureType )).ToString());

    Tests

    Disable functional test

    Functional tests are disabled in the <Project root>/Config/DefaultEngine.ini file.
    Under the [AutomationTestExcludelist] section add a new line:

    The test value is a path. If the test is added to a map, then the path looks like “Project.Functional”<map path above the content directory, so Content/Tests/Assets/map.umap will be Tests.Assets><name of the map><outline structure, so if your test is in a directory in the level called test, then “Test” is added><name of the test in the level>

    Example:
    – level: Content/Tests/Maps1/TestMap1.umap
    – in the map: Test/Test_1
    Then this is Test=”Project.Functional Tests.Maps1.TestMap1.Test.Test_1″

    +ExcludeTest=(Map="",Test="Project.Functional Tests.Maps1.TestMap1.Test.Test_1",Reason="This test will be disabled now",RHIs=(),Warn=False)
    

    Validators

    C++ validators

    Here’s a minimal c++ validator header file

    UCLASS()
    class UAssetValidator_Filenames : public UEditorValidatorBase
    {
        GENERATED_BODY()
    
        virtual bool CanValidateAsset_Implementation(const FAssetData& InAssetData, UObject* InAsset, FDataValidationContext& InContext) const override;
        virtual EDataValidationResult ValidateLoadedAsset_Implementation(const FAssetData& InAssetData, UObject* InAsset, FDataValidationContext& InContext) override;
    };

    How to check can validate asset

    Check if asset is data table of my specific type:
    bool UAssetValidator_Filenames::CanValidateAsset_Implementation(const FAssetData& InAssetData, UObject* InAsset, FDataValidationContext& InContext) const
    {
        if (const UDataTable* LocalDataTable = Cast<UDataTable>(InAsset))
        {
            return FMyDataTableRowStruct::StaticStruct() == LocalDataTable->RowStruct;
        }
    
        return false;
    }

    Write own settings in c++

    UCLASS(Config = Game, defaultconfig)
    class MYPLUGIN_API UMySettings : public UDeveloperSettings
    {
    	GENERATED_UCLASS_BODY()
    
    	UPROPERTY(Config, EditAnywhere)
    	TArray<FDirectoryPath> Paths;
    }

    By declaring this class, you will find an array of paths in the UE -> Project Settings -> MyPlugin

    Logs

    Declare log verbosity. If you want to print Verbose logs, in any .h file write:

    MYPLUGIN_API DECLARE_LOG_CATEGORY_EXTERN(LogMyPlugin, Verbose, All);

    Unreal Asserts

    Check

    Using check will crash the game with the message you provided in check. Not called in shipping build

    Verify

    Crashes the game, the same as check, but is called in all builds.

    Ensure

    Posts an error in the log

    example of ensure with text that will post error to console each time it is encountered:

    ensureAlwaysMsgf(true, TEXT("This is error message posted to logs %s"), *MyString)

    Editor settings

    auto load last opened level

    Editor Preferences – General – Loading & Saving – Load Level at Startup – Last Opened

    don’t quit PIE with Esc

    Editor Preferences – General – Keyboard Shortcuts – Play World (PIE/SIE) – Stop (Stop simulation) – Change from Escape to Ctrl + Q

    Editor customization

    1. Header
      • IPropertyTypeCustomization::CustomizeHeader
    2. Children
      • IPropertyTypeCustomization::CustomizeChildren
    virtual void CustomizeHeader(TSharedRef<class IPropertyHandle> InStructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override;
    
    HeaderRow.NameContent()[InStructPropertyHandle->CreatePropertyNameWidget()]