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
- 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
- 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:
- https://devblogs.microsoft.com/visualstudio/customize-object-displays-in-the-visual-studio-debugger-your-way/
- https://dev.epicgames.com/community/learning/tutorials/dXl5/advanced-debugging-in-unreal-engine – navigate to Visual Studio & Unreal Engine – Natvis. This also applies to Rider
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
- Header
- IPropertyTypeCustomization::CustomizeHeader
- Children
- IPropertyTypeCustomization::CustomizeChildren
virtual void CustomizeHeader(TSharedRef<class IPropertyHandle> InStructPropertyHandle, class FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; HeaderRow.NameContent()[InStructPropertyHandle->CreatePropertyNameWidget()]
Dropdown instead of FName in function parameters
UFUNCTION(BlueprintCallable)
static void MethodName(UPARAM(meta = (GetOptions = "GetSlotNameOptions")) FName SlotName);
UFUNCTION()
static TArray<FName> GetSlotNameOptions();
This method will generate a dropdown instead of a text box in the blueprint context when calling this method.
GAS
Filtering gameplay tags in function parameters
If you want to filter a GameplayTag
(or GameplayTagContainer) parameter in a function, use the UFUNCTION
specifier Meta = (GameplayTagFilter = "ItemType")
.