UE 小妙招
外部访问私有成员
模板加友元访问未被UPROPERTY标记的私有成员
//宏定义
#define ACCESS_MEMBER(ClassName, Member,MemberType) \
template<auto M>\
struct Accessor_##ClassName##Member;\
template<class T, class U, T U::*M>\
struct Accessor_##ClassName##Member<M> {\
friend T& Get##Member##From##ClassName(U& u) {\
return u.*M;\
}\
};\
\
template struct Accessor_##ClassName##Member<&ClassName::Member>;\
MemberType& Get##Member##From##ClassName(ClassName&);\
//在项目的某个地方,我们要取出UGameInstance类的SubsystemCollection成员,它是个private 属性,它的类型是FObjectSubsystemCollection<UGameInstanceSubsystem>
//直接写这么一行
ACCESS_MEMBER(UGameInstance,SubsystemCollection,FObjectSubsystemCollection<UGameInstanceSubsystem>)
//调用,这其实是UGameInstance::Init()的内容,但是我想要自定义初始化,只能这样了
GetSubsystemCollectionFromUGameInstance(*this).Initialize(this);
消灭编译时的奇怪报错
Win标头问题:Unreal重定义了Windows中的各种宏,所以需要检查整个代码项目是否引用了任何Windows头文件,包括项目的第三方库。这些标头文件应按照以下的方式包裹:
#include "Windows/AllowWindowsPlatformTypes.h" THIRD_PARTY_INCLUDES_START // Windows + third-party includes THIRD_PARTY_INCLUDES_END #include "Windows/HideWindowsPlatformTypes.h"
在代码中定义GameplayTags
在代码中使用GameplayTags通常是填字符串既不优雅也不便维护,直接在代码中声明GameplayTag才是正解
//比如我们可与在一个插件的某个模块中声明
//.h文件
XXXXXXXXXX_API UE_DECLARE_GAMEPLAY_TAG_EXTERN(TAG_Cheat_GodMode)
//.cpp文件
UE_DEFINE_GAMEPLAY_TAG_COMMENT(TAG_Cheat_GodMode, "Cheat.GodMode", "GodMode 作弊功能已在owner身上激活");
//如此一来,不需要在编辑器中设置任何Gameplay Tag,将所有标签定义到代码里,其他地方直接使用TAG_Cheat_GodMode。
引入第三方库
静态库
//xxx.Build.cs
string ThirdPartyPath => Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty/"));
public XXXXX(ReadOnlyTargetRules Target) : base(Target)
{
...
...
string includePath = Path.Combine(ThirdPartyPath, "include");
PublicIncludePaths.Add(includePath);
string libPath = Path.Combine(Path.Combine(ThirdPartyPath, "lib"), "lunasvg.lib");
PublicAdditionalLibraries.Add(libPath);
}
动态库
//xxx.Build.cs
string ThirdPartyPath => Path.GetFullPath(Path.Combine(ModuleDirectory, "../ThirdParty/"));
public XXXXX(ReadOnlyTargetRules Target) : base(Target)
{
...
...
PublicIncludePaths.Add(Path.Combine(ThirdPartyPath, "include"));
string dllPath = Path.Combine(Path.Combine(ThirdPartyPath, "lib"), "wgpu_native.dll");
string libPath = Path.Combine(Path.Combine(ThirdPartyPath, "lib"), "wgpu_native.dll.lib");
PublicAdditionalLibraries.Add(libPath);
PublicDelayLoadDLLs.Add(dllPath);
RuntimeDependencies.Add(dllPath, libPath);
PublicDefinitions.Add(string.Format("__EMSCRIPTEN__={0}", 0));
}
除此之外,还需要再模块启动时加载dll
void XXXXX::StartupModule()
{
const FString BasePluginDir = IPluginManager::Get().FindPlugin("XXXXX")->GetBaseDir();
const FString LibExamplePath = FPaths::Combine(*BasePluginDir,TEXT("Source/ThirdParty/lib/wgpu_native.dll"));
DynamicLibHandle_WebGPU = FPlatformProcess::GetDllHandle(*LibExamplePath);
}
void XXXXX::ShutdownModule()
{
if(DynamicLibHandle_WebGPU) FPlatformProcess::FreeDllHandle(DynamicLibHandle_WebGPU);
}
覆盖Actor父类的组件
Character类有一个CharacterMovementComponent组件,可以通过ObjectInitializer使用自己创建的组件,当然必须得是父组件的子类
ACHA_Base::ACHA_Base(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UMyMovementComponent>(
ACharacter::CharacterMovementComponentName))
{
......
}
UBT编译
修改MSVC工具和Windows Kti版本
通过BuildConfiguration.xml可以对UBT的行为做出设置,例如:
WindowsSdkVersion:使用特定的Windows Kit版本
ToolchainVersion:使用特定的MSVC版本
Windows Kit移动位置导致的报错
别问我为什么会移动Windows Kit的安装位置,问就是VS原地拉屎
修改注册表:
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Microsoft SDKs\Windows\v10.0的InstallationFolder
HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots的KitsRoot10
原创文章,转载请注明来自 Unbound Fanatic
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果