UE4是以Module(模块)来组织代码,但是目前创建custom module不是一件很方便的事情。具体方法可参考:
http://orfeasel.com/creating-custom-modules/
Plugin与module都能起到组织代码的作用。创建plugin(插件)就方便许多了,Editor里有plugins管理器。
1. ActionRPG.Target.cs & ActionPRGEditot.Target.cs
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class ActionRPGTarget : TargetRules
{
public ActionRPGTarget(TargetInfo Target)
: base(Target)
{
Type = TargetType.Game;
ExtraModuleNames.AddRange(new string[] { "ActionRPG" });
}
}
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class ActionRPGEditorTarget : TargetRules
{
public ActionRPGEditorTarget(TargetInfo Target)
: base(Target)
{
Type = TargetType.Editor;
ExtraModuleNames.AddRange(new string[] { "ActionRPG" });
}
}
每个ue项目都会自动生成该文件,主要是定义了Type和ExtraModule。ActionRPG项目没有对这里做出修改。
更多的信息可以查看文件:
/UE_4.22/Engine/Source/Programs/UnrealBuildTool/Configuration/TargetRule.cs
2. ActionRPG.Build.cs & ActionRPGLoadingScreen.Build.cs
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class ActionRPG : ModuleRules
{
public ActionRPG(ReadOnlyTargetRules Target)
: base(Target)
{
PrivatePCHHeaderFile = "Public/ActionRPG.h";
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"Engine"
}
);
PrivateDependencyModuleNames.AddRange(
new string[] {
"ActionRPGLoadingScreen",
"Slate",
"SlateCore",
"InputCore",
"MoviePlayer",
"GameplayAbilities",
"GameplayTags",
"GameplayTasks"
}
);
if (Target.Platform == UnrealTargetPlatform.IOS)
{
PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "OnlineSubsystemUtils" });
DynamicallyLoadedModuleNames.Add("OnlineSubsystemFacebook");
DynamicallyLoadedModuleNames.Add("OnlineSubsystemIOS");
DynamicallyLoadedModuleNames.Add("IOSAdvertising");
}
else if (Target.Platform == UnrealTargetPlatform.Android)
{
PrivateDependencyModuleNames.AddRange(new string[] { "OnlineSubsystem", "OnlineSubsystemUtils" });
DynamicallyLoadedModuleNames.Add("AndroidAdvertising");
DynamicallyLoadedModuleNames.Add("OnlineSubsystemGooglePlay");
// Add UPL to add configrules.txt to our APK
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("AndroidPlugin", System.IO.Path.Combine(PluginPath, "AddRoundIcon_UPL.xml"));
}
}
}
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
// This module must be loaded "PreLoadingScreen" in the .uproject file, otherwise it will not hook in time!
public class ActionRPGLoadingScreen : ModuleRules
{
public ActionRPGLoadingScreen(ReadOnlyTargetRules Target)
: base(Target)
{
PrivatePCHHeaderFile = "Public/ActionRPGLoadingScreen.h";
PCHUsage = PCHUsageMode.UseSharedPCHs;
PrivateIncludePaths.Add("ActionRPGLoadingScreen/Private");
PublicDependencyModuleNames.AddRange(
new string[] {
"Core",
"CoreUObject",
"Engine"
}
);
PrivateDependencyModuleNames.AddRange(
new string[] {
"MoviePlayer",
"Slate",
"SlateCore",
"InputCore"
}
);
}
}
ActionRPG中除了默认生成的ActionRPG module之外,还创建了ActionRPGLoadingScreen module。.Build.cs文件就是对模块间的依赖关系、文件路径、PCH的使用、平台差异等进行配置。
PCH
Pre-compile header(PCH)指预编译头文件,该头文件只编译一次,通常包含对工程中大量使用、且不会被修改的头文件的引用。如这里的ActionRPG.h
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
#pragma once
// ----------------------------------------------------------------------------------------------------------------
// This header is included by all headers in the project so it's a good place to declare common includes
// We include EngineMinimal and the subset of engine headers used by most of our classes
// We don't want to include "Engine.h" as that pulls in too many classes we don't need and slows compile time
// ----------------------------------------------------------------------------------------------------------------
#include "EngineMinimal.h"
#include "Engine/Engine.h"
#include "Net/UnrealNetwork.h"
#include "RPGTypes.h"
//这是添加了自定义的log标签
ACTIONRPG_API DECLARE_LOG_CATEGORY_EXTERN(LogActionRPG, Log, All);
DependencyModuleName
在这里添加该module对其他module的依赖,public和private区别在于,当别人引用我们写的模块时,他的模块会继承我们的public依赖,不会继承private依赖。
关于.Build.cs中更多信息,可以查阅:
/UE_4.22/Engine/Source/Programs/UnrealBuildTool/Configuration/ModuleRules.cs
3. ActionRPG.urpoject
{
"FileVersion": 3,
"EngineAssociation": "4.22",
"Category": "Samples",
"Description": "",
"Modules": [
{
"Name": "ActionRPG",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "ActionRPGLoadingScreen",
"Type": "ClientOnly",
"LoadingPhase": "PreLoadingScreen"
}
],
"Plugins": [
{
"Name": "AppleARKit",
"Enabled": false
},
{
"Name": "ArchVisCharacter",
"Enabled": false
},
{
"Name": "AudioCapture",
"Enabled": false
},
{
"Name": "CryptoKeys",
"Enabled": false
},
{
"Name": "CustomMeshComponent",
"Enabled": false
},
{
"Name": "DatasmithContent",
"Enabled": false
},
{
"Name": "HTML5Networking",
"Enabled": false
},
{
"Name": "FacialAnimation",
"Enabled": false
},
{
"Name": "GameplayAbilities",
"Enabled": true
},
{
"Name": "ImmediatePhysics",
"Enabled": false
},
{
"Name": "LinearTimecode",
"Enabled": false
},
{
"Name": "OculusVR",
"Enabled": false
},
{
"Name": "PhysXVehicles",
"Enabled": false
},
{
"Name": "ResonanceAudio",
"Enabled": false
},
{
"Name": "SteamVR",
"Enabled": false
},
{
"Name": "ProceduralMeshComponent",
"Enabled": false
},
{
"Name": "RuntimePhysXCooking",
"Enabled": false
},
{
"Name": "UObjectPlugin",
"Enabled": false
},
{
"Name": "WindowsMoviePlayer",
"Enabled": false
},
{
"Name": "WmfMedia",
"Enabled": false
},
{
"Name": "CableComponent",
"Enabled": false
},
{
"Name": "CharacterAI",
"Enabled": false
},
{
"Name": "LightPropagationVolume",
"Enabled": false
},
{
"Name": "MediaCompositing",
"Enabled": false
},
{
"Name": "LocationServicesBPLibrary",
"Enabled": false
},
{
"Name": "SlateRemote",
"Enabled": true
},
{
"Name": "MagicLeapEmulator",
"Enabled": false,
"SupportedTargetPlatforms": [
"Lumin"
]
},
{
"Name": "MagicLeapMedia",
"Enabled": false,
"SupportedTargetPlatforms": [
"Lumin"
]
},
{
"Name": "MagicLeap",
"Enabled": false,
"SupportedTargetPlatforms": [
"Lumin"
]
}
],
"TargetPlatforms": [
"Android",
"IOS",
"WindowsNoEditor",
"MacNoEditor"
],
"EpicSampleNameHash": "2961006109"
}
这里有关于ue版本的配置,还可以配置module的type和加载阶段,当你使用Editor中plugins管理器管理插件,实际上也会修改这里。通常来说,这个文件不需要你过多的关注,你知道有即可。
上面提及的文件其实都是与UnrealBuildTool相关的,在VS中发现编译错误跟UBT有关,那么就有可能需要对这些文件做修改。由于对UBT的了解不深,所以暂时就到此为止了。