本文目的是将在Unreal Engine 4开发中遇到的一些问题及解决方案记录下来,方便以后查找。
版本:4.18
问题一:
在编译如下代码时:
UWidgetComponent* WidgetComponent = Cast(this->GetComponentByClass(UWidgetComponent::StaticClass()));
报如下错误:
error LNK2019: unresolved external symbol
"__declspec(dllimport) private: static class UClass * __cdecl UWidgetComponent::GetPrivateStaticClass(void)"
(__imp_?GetPrivateStaticClass@UWidgetComponent@@CAPEAVUClass@@XZ)
referenced in function "protected: virtual void __cdecl ATankModel::BeginPlay(void)" (?BeginPlay@ATankModel@@MEAAXXZ)
从错误信息中看,好像是UWidgetComponent::GetPrivateStaticClass(void)方法未找到。但实际上UWidgetComponent中并不存在此方法。而此问题实际上是由于UWidgetComponent所在的模块UMG,没有加入到需要编译的模块中造成的。修改方式为在工程的.Build.cs文件的编译选项中添加此模块:
using UnrealBuildTool;
public class ClientProj : ModuleRules
{
public ClientProj(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(
new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
}
}
问题二:
在编译如下代码时:
template
ValueBoxImpl& getValueBox(std::shared_ptr valueBox_ptr) {
return dynamic_cast&>(*valueBox_ptr);
};
报如下错误:
C:\Epic Games\UE_4.18\Engine\Source\Runtime\CoreUObject\Public\Templates/Casts.h(413):
error C4541: 'dynamic_cast' used on polymorphic type 'tanx::ValueBox' with /GR-;
unpredictable behavior may result
错误原因是RTTI未启用,需要在.Build.cs文件中启用RTTI功能:
using UnrealBuildTool;
public class ClientProj : ModuleRules
{
public ClientProj(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
bUseRTTI = true;
PublicDependencyModuleNames.AddRange(
new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
}
}
问题三:
在编译如下代码时:
class GameHome {
private:
AClientProjGameModeBase& gameMode;
}
报如下错误:
game_home.h(16): error C2143: syntax error: missing ';' before '&'
game_home.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
game_home.h(16): error C2238: unexpected token(s) preceding ';'
错误原因在于没有在ATanxClientProjGameModeBase前加上class,修改后编译通过:
class GameHome {
private:
class AClientProjGameModeBase& gameMode;
}
从这个例子可以看到,从unreal提供的类作为父类衍生出的类,在使用时最好都加上class来修饰。
问题四:
编译打包时报如下错误:
error C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
原因在于C++中使用了exception处理的机制。修改方法是在.Build.cs文件中打开相关的编译选项“bEnableExceptions”:
using UnrealBuildTool;
public class ClientProj : ModuleRules
{
public ClientProj(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
bUseRTTI = true;
bEnableExceptions = true;
PublicDependencyModuleNames.AddRange(
new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UMG" });
}
}
问题五:
在新开的线程中调用SpawnActor,应用会崩溃或什么结果也没有。
SpawnActor必须在game thread中被调用,如果不在game thread中被调用,可能会导致系统自动退出。可以通过check(IsInGameThread());来检测当前线程是否是game thread。
问题六:
在Plugins中设置了
bUseRTTI = true;
bEnableExceptions = true;
结果打包Windows应用时,报如下警告和错误:
warning C4652: compiler option 'C++ Exception Handling Unwinding' inconsistent with precompiled header; current command-line option will override that defined in the precompiled header
warning C4651: '/D_HAS_EXCEPTIONS=0' specified for precompiled header but not for current compile
error LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl std::bad_cast::bad_cast(char const *)"
造成此问题的原因是
UE_4.18\Engine\Intermediate\Build\Win64\UE4\Development\Engine\SharedPCH.Engine.RTTI.h
在编译成
UE_4.18\Engine\Intermediate\Build\Win64\UE4\Development\Engine\SharedPCH.Engine.RTTI.h.pch
的过程中没有设置bEnableExceptions = true;
需要修改UE_4.18\Engine\Source\Programs\UnrealBuildTool\Configuration\UEBuildModuleCPP.cs
// 修改前
public PrecompiledHeaderInstance FindOrCreateSharedPCH(UEToolChain ToolChain, PrecompiledHeaderTemplate Template, bool bOptimizeCode, bool bUseRTTI, ActionGraph ActionGraph)
// 修改后
public PrecompiledHeaderInstance FindOrCreateSharedPCH(UEToolChain ToolChain, PrecompiledHeaderTemplate Template, bool bOptimizeCode, bool bUseRTTI, bool bEnableExceptions, ActionGraph ActionGraph)
并在此函数中添加
CompileEnvironment.bEnableExceptions = bEnableExceptions;
将
// 修改前
PrecompiledHeaderInstance Instance = FindOrCreateSharedPCH(ToolChain, Template, ModuleCompileEnvironment.bOptimizeCode, ModuleCompileEnvironment.bUseRTTI, ActionGraph);
// 修改后
PrecompiledHeaderInstance Instance = FindOrCreateSharedPCH(ToolChain, Template, ModuleCompileEnvironment.bOptimizeCode, ModuleCompileEnvironment.bUseRTTI, ModuleCompileEnvironment.bEnableExceptions, ActionGraph);
再编译打包Windows应用时就不会报错了。