Поддержка блупринт-нативизации

Blueprint nativization конвертирует визуализированный блупринт-код какой-нибудь ноды в её C++ реализацию, что досрочно компилируется, а не интерпретируется в процессе игры. Для сложных сценариев это может работать гораздо быстрее, так как C++ компиляторы богаты на оптимизации.

К несчастью, Unreal Engine не поддерживает нативизацию функций, выполняющих манипуляции с виртуальной машиной блупринтов. Apparatus - достаточно низкоуровневый инструмент с набором функций конкретно такого рода, поэтому, когда вы помечаете свою механику как нативизируемую (nativized) и затем пакуете сборку, вы можете получить примерно такое сообщение в консоли

UATHelper: Packaging (Windows (64-bit)):     .../Intermediate/Plugins/NativizedAssets/Windows/Game/Source/NativizedAssets/Private/...cpp(657): error C3861: 'GetChunkChainTraitAt': identifier not found
UATHelper: Packaging (Windows (64-bit)):     .../Intermediate/Plugins/NativizedAssets/Windows/Game/Source/NativizedAssets/Private/...cpp(783): error C2039: 'SetSubjectTrait': is not a member of 'FCustomThunkTemplates'

Нам повезло: есть довольно лёгкие обходные пути, чтобы избежать этой проблемы.

На самом деле, вы можете вполне безболезненно поменять один заголовочный файл в папке Unreal. Он находится по пути: C:\Program Files\Epic Games\UE_4.26\Engine\Source\Runtime\Engine\Public\GeneratedCodeHelpers.h

Откройте этот файл в предпочитаемом текстовом редакторе и добавьте следующий код в конец структуры FCustomThunkTemplates. В версии 4.26 структура объявлена в строчке 89. Вы можете добавить вот этот фрагмент в публичную секцию структуры public:.

#pragma region Apparatus Nativization Support

	template <typename TSubjectHandle>
	static void
	SetSubjectTrait(TSubjectHandle& SubjectHandle,
					UScriptStruct* TraitType,
					void* InTraitData)
	{
		SubjectHandle.SetTrait(TraitType, InTraitData);
	}

	template <typename TSubjectHandle, typename T>
	static void
	SetSubjectTrait(TSubjectHandle& SubjectHandle,
					UScriptStruct*  TraitType,
					const T&        InTraitData)
	{
		SubjectHandle.SetTrait(TraitType, (const void* const)&InTraitData);
	}

	template <typename TSubjectHandle>
	static void
	ObtainSubjectTrait(TSubjectHandle& SubjectHandle,
					   UScriptStruct*  TraitType,
					   void* const     OutTraitData)
	{
		SubjectHandle.ObtainTrait(TraitType, OutTraitData);
	}

	template <typename TSubjectHandle, typename T>
	static void
	ObtainSubjectTrait(TSubjectHandle& SubjectHandle,
					   UScriptStruct*  TraitType,
					   T*              OutTraitData)
	{
		SubjectHandle.ObtainTrait(TraitType, (void* const)&OutTraitData);
	}

	template <typename TSubjectHandle>
	static void
	GetSubjectTrait(TSubjectHandle& SubjectHandle,
					UScriptStruct*  TraitType,
					void* const     OutTraitData)
	{
		SubjectHandle.GetTrait(TraitType, OutTraitData);
	}

	template <typename TSubjectHandle, typename T>
	static void
	GetSubjectTrait(TSubjectHandle& SubjectHandle,
					UScriptStruct*  TraitType,
					T&              OutTraitData)
	{
		SubjectHandle.GetTrait(TraitType, (void* const)&OutTraitData);
	}

	template <typename T>
	static void
	GetChunkChainTraitAt(const int32& ChunkChainId,
						 const int32  TraitIndex,
						 T&           OutTraitData)
	{
		ensure(UMachine::ObtainChunkChain(ChunkChainId).GetTraitAt(TraitIndex, (void* const)&OutTraitData)
			   >= EApparatusStatus::Success);
	}

	template <typename T>
	static void
	GetChunkChainTraitAt(const int32& ChunkChainId,
						 const int32  TraitIndex,
						 T* const     OutTraitData)
	{
		ensure(UMachine::ObtainChunkChain(ChunkChainId).GetTraitAt(TraitIndex, (void* const)OutTraitData)
			   >= EApparatusStatus::Success);
	}

#pragma endregion Apparatus Nativization Support