English | 简体中文
Not LexToString, not JSON — compile-time debug stringify for UE containers and pointers.
Unreal Engine plugin that converts values to FString via UStrify::ToString. Overload selection is compile-time (SFINAE / if constexpr). Types can opt in with a ToString() member.
- Unreal Engine 5.6+
- Copy
Plugins/Strifyinto your project'sPluginsdirectory. - Enable the plugin in the
.uproject:
"Plugins": [
{ "Name": "Strify", "Enabled": true }
]- Add the module to any
Build.csthat includes the headers:
PublicDependencyModuleNames.Add("Strify");This repository is a UE 5.6 sample project (StrifyTest) that already contains the plugin.
#include "Strify.h"
FString IntStr = UStrify::ToString(42);
TArray<int32> Numbers = {1, 2, 3};
FString ArrayStr = UStrify::ToString(Numbers); // [1, 2, 3]
FString Multiline = UStrify::ToString(Numbers, true); // [\n1,\n2,\n3\n]
UE_LOG(LogTemp, Display, TEXT("%s"), *ArrayStr);Logging TMap<uint64, TSet<int32>>:
// Before
UE_LOG(LogTemp, Display, TEXT("IdToValues: %s"), *FString::JoinBy(IdToValues, TEXT(","), [](const TPair<uint64, TSet<int32>>& Pair) {
return FString::Printf(TEXT("{%llu:[%s]}"), Pair.Key, *FString::JoinBy(Pair.Value, TEXT(","), [](int32 Value) {
return FString::Printf(TEXT("%d"), Value);
}));
}));
// After — second arg is Multilines
UE_LOG(LogTemp, Display, TEXT("IdToValues: %s"), *UStrify::ToString(IdToValues, true));- Less to type.
- The map used to be
TMap<uint64, TArray<int32>>, then becameTMap<uint64, TSet<int32>>. NestedFString::JoinBylambdas must change parameter types;UStrify::ToStringdoes not.
Add FString ToString() const on a struct or UObject subclass; THasToStringFunc detects it:
struct FMyStruct
{
int32 Value1;
float Value2;
FString ToString() const
{
return FString::Printf(TEXT("MyStruct(%d,%f)"), Value1, Value2);
}
};| Kind | Result |
|---|---|
| Integers | Decimal |
| Floating point | Three decimal places (%.3f) |
bool |
true / false |
FString |
Unchanged |
UENUM enum class |
Reflection name |
TEnumAsByte<T> |
UEnum::GetValueAsString |
| Other enums | TypeName(underlying) |
Types with ToString() |
That member |
UObject without ToString() |
<unsupported {ClassName}: {GetName()}> |
| Raw, shared, unique, weak, and object pointers | Recurse if valid; "" if null or stale |
FVariant |
Routed by stored type; unknown → <unsupported variant: EVariantTypes(N)> |
TArray |
[a, b, c] |
TSet |
(a, b, c) |
TMap |
{key: value, ...} |
| Byte buffers | UStrify::ToHexString — uppercase hex, no separators |
Empty containers stringify to "". Null or empty elements inside a container keep a slot ([1, , 3]). Nested containers recurse.
TypeTraits.h:
TIsContainer<T>—begin(),end(), andIsEmpty()THasToStringFunc<T>—FString ToString()(viaDECLARE_HASFUNCTION_TYPETRAITS)Strify::GetTypeName<T>()— compiler signature (__FUNCSIG__/__PRETTY_FUNCTION__), no UE reflection
static_assert(TIsContainer<TArray<int32>>::Value);
static_assert(!TIsContainer<int32>::Value);Editor automation specs are in Plugins/Strify/Source/Strify/Private/Tests (Strify.UnitTests).
MIT. When used with Unreal Engine, the Epic Games Unreal Engine EULA still applies.