UE4开发的问题笔记和资料辑录

在平时的开发和学习中遇到和解决的一些问题以及摘录的一些资料,都随手写在了notes中,UE相关的积攒了不少,其他的混在一起比较混乱,整理到本篇文章中。
UE4和VR开发技术笔记不同的是,这里的内容更偏向于项目中实际的问题记录和资料收集。

UE4 Error:The game module 'xxx' could not be loaded.

如果项目启动时弹窗以下错误:

1
The game module 'WebBrowserEx' could not be loaded. There may be an operating system error or the module may not be properly set up.

造成这个问题的原因之一是这个模块中引用了外部的Plugin,需要在这个模块的uplugin文件中增加Plugins依赖项。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "PluginA",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"Installed": false,
"Modules": [
{
"Name": "PluginA",
"Type": "Developer",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "PluginB",
"Enabled": true
}
]
}

UE4 Error:must include the same precompiled header first.

编译时如果出现这样的错误:

1
2
3
4
5
6
7
8
9
10
11
12
1>------ Build started: Project: NetExampleDemo, Configuration: Development_Game x64 ------
1>Performing full C++ include scan (building a new target)
1>Creating makefile for NetExampleDemo (changes to module files)
1>EXEC : error : All source files in module "WebBrowserEx" must include the same precompiled header first. Currently "C:\Users\visionsmile\Documents\Unreal Projects\Examples\NetExampleDemo\Plugins\WebBrowserEx\Source\WebBrowserEx\Public\WebBrowserEx.h" is included by most of the source files. The following source files are not including "C:\Users\visionsmile\Documents\Unreal Projects\Examples\NetExampleDemo\Plugins\WebBrowserEx\Source\WebBrowserEx\Public\WebBrowserEx.h" as their first include:
1>
1> C:\Users\visionsmile\Documents\Unreal Projects\Examples\NetExampleDemo\Plugins\WebBrowserEx\Source\WebBrowserEx\Private\WebBrowserExWidget.cpp (including C:\Users\visionsmile\Documents\Unreal Projects\Examples\NetExampleDemo\Plugins\WebBrowserEx\Source\WebBrowserEx\Public\WebBrowserExWidget.h)
1>
1>
1> To compile this module without implicit precompiled headers, add "PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;" to WebBrowserEx.build.cs.
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCTargets\Microsoft.MakeFile.Targets(44,5): error MSB3075: The command ""C:\Program Files\Epic Games\UE_4.18\Engine\Build\BatchFiles\Build.bat" NetExampleDemo Win64 Development "C:\Users\visionsmile\Documents\Unreal Projects\Examples\NetExampleDemo\NetExampleDemo.uproject" -waitmutex" exited with code 5. Please verify that you have sufficient rights to run this command.
1>Done building project "NetExampleDemo.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

则需要在*.build.cs中添加:

1
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

UE4:UWebBrowser支持中文输入

UE的UWebBrowser打开的页面不支持中文输入,可以使用以下办法开启。
继承UWebBrowser重写RebuildWidget,增加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
TSharedRef<SWidget> UWebBrowserExWidget::RebuildWidget()
{
if (IsDesignTime())
{
return SNew(SBox)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(LOCTEXT("Web Browser", "Web Browser"))
];
}
else
{
WebBrowserWidget = SNew(SWebBrowser)
.InitialURL(InitialURL)
.ShowControls(false)
.SupportsTransparency(bSupportsTransparency)
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleOnUrlChanged));
// support chinese input
if (WebBrowserWidget.IsValid())
{
class ITextInputMethodSystem* const TextInputMethodSystem = FSlateApplication::Get().GetTextInputMethodSystem();
WebBrowserWidget->BindInputMethodSystem(TextInputMethodSystem);
}

return WebBrowserWidget.ToSharedRef();
}

}

我把它单独做了一个插件,GitHub地址为:hxhb/WebBrowserEx418.

UE4:UnrealBuildTool Dependancy Warning

1
UnrealBuildTool: Warning: Plugin 'A' does not list plugin 'B' as a dependency, but module 'A' depends on 'B'

在插件A的.uplugin文件中添加Plugins项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "PluginA",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"Installed": false,
"Modules": [
{
"Name": "PluginA",
"Type": "Developer",
"LoadingPhase": "Default"
}
],
"Plugins": [
{
"Name": "PluginB",
"Enabled": true
}
]
}

UE4:Instanced Stereo Rendering

在UE4.11中引入了Instanced Stereo Rendering,其原理是通过单次draw call来绘制双眼,进而来缩短渲染线程的时间和提高GPU的性能。

开启方式(ProjectSetting-Engine-Rending):

UE4:HandleNetworkFailure

在UE中当网络连接出现错误时会调用UEngine::HandleNetworkFailure来接收错误消息和处理错误,错误的类型为枚举ENetworkFailure::Type,标识了几种网络的错误类型。
以Server拒绝玩家的加入为例,在UE的这套网络架构中,使用CreateSession/JoinSession的方式来创建/加入游戏,可以通过AGameModeBase::Prelogin以及overwrite了该成员函数的子类来拒绝玩家的加入,方法为返回的ErrorMessage不为空即为拒绝:

1
2
3
4
5
6
7
8
9
10
/**
* Accept or reject a player attempting to join the server. Fails login if you set the ErrorMessage to a non-empty string.
* PreLogin is called before Login. Significant game time may pass before Login is called
*
* @param Options The URL options (e.g. name/spectator) the player has passed
* @param Address The network address of the player
* @param UniqueId The unique id the player has passed to the server
* @param ErrorMessage When set to a non-empty value, the player will be rejected using the error message set
*/
virtual void PreLogin(const FString& Options, const FString& Address, const FUniqueNetIdRepl& UniqueId, FString& ErrorMessage);

GameMode的PreLogin调用栈为:

当玩家被拒绝加入游戏时,服务器会发送给当前连接的客户端错误消息:

1
2
3
// call in server send to client
// function is UWorld::NotifyControlMessage
FNetControlMessage<NMT_Failure>::Send(Connection, ErrorMsg);

PS:FNetControlMessage<T>::Send的实现是由DEFINE_CONTROL_CHANNEL_MESSAGE_ONEPARAM宏包裹的,其定义在文件DataChannel.h中。
该消息会发送到客户端上,通过UEngine::HandleNetworkError来使客户端来处理该错误,在其中会通知到UGameInstance::HandleNetworkError,但是并没有把ErrorMessage传递给GameInstance,我们可以通过继承UGameEngine重写HandleNetworkError来将ErrorMessage传递给外部。

PS:玩家被拒绝之后会回到项目设置里的Game Default Map中。

UGameInstance::HandleNetworkError

当网络链接出现错误时,会调用该函数(服务端拒绝玩家加入时也会调用)。

调用栈为(可以继承UEngine来替换Engine实现):

1
UEngine::HandleNetworkError -> UEngine::HandleNetworkFailure_NotifyGameInstance -> GameInstance->HandleNetworkError(FailureType, bIsServer);

VS断点调用栈:

UEngine::HandleNetworkFailure实现为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Runtime\Source\Runtime\Engine\Private\UnrealEngine.cpp
void UEngine::HandleNetworkFailure(UWorld *World, UNetDriver *NetDriver, ENetworkFailure::Type FailureType, const FString& ErrorString)
{
UE_LOG(LogNet, Log, TEXT("NetworkFailure: %s, Error: '%s'"), ENetworkFailure::ToString(FailureType), *ErrorString);

if (!NetDriver)
{
return;
}

// Only handle failure at this level for game or pending net drivers.
FName NetDriverName = NetDriver->NetDriverName;
if (NetDriverName == NAME_GameNetDriver || NetDriverName == NAME_PendingNetDriver)
{
// If this net driver has already been unregistered with this world, then don't handle it.
if (World)
{
if (!FindNamedNetDriver(World, NetDriverName))
{
// This netdriver has already been destroyed (probably waiting for GC)
return;
}
}

// Give the GameInstance a chance to handle the failure.
HandleNetworkFailure_NotifyGameInstance(World, NetDriver, FailureType);

ENetMode FailureNetMode = NetDriver->GetNetMode(); // NetMode of the driver that failed
bool bShouldTravel = true;

switch (FailureType)
{
case ENetworkFailure::FailureReceived:
break;
case ENetworkFailure::PendingConnectionFailure:
// TODO stop the connecting movie
break;
case ENetworkFailure::ConnectionLost:
// Hosts don't travel when clients disconnect
bShouldTravel = (FailureNetMode == NM_Client);
break;
case ENetworkFailure::ConnectionTimeout:
// Hosts don't travel when clients disconnect
bShouldTravel = (FailureNetMode == NM_Client);
break;
case ENetworkFailure::NetGuidMismatch:
case ENetworkFailure::NetChecksumMismatch:
// Hosts don't travel when clients have actor issues
bShouldTravel = (FailureNetMode == NM_Client);
break;
case ENetworkFailure::NetDriverAlreadyExists:
case ENetworkFailure::NetDriverCreateFailure:
case ENetworkFailure::OutdatedClient:
case ENetworkFailure::OutdatedServer:
default:
break;
}

if (bShouldTravel)
{
CallHandleDisconnectForFailure(World, NetDriver);
}
}
}

void UEngine::HandleNetworkFailure_NotifyGameInstance(UWorld *World, UNetDriver *NetDriver, ENetworkFailure::Type FailureType)
{
bool bIsServer = true;

if (NetDriver != nullptr)
{
bIsServer = NetDriver->GetNetMode() != NM_Client;
}

if (World != nullptr && World->GetGameInstance() != nullptr)
{
World->GetGameInstance()->HandleNetworkError(FailureType, bIsServer);
}
else
{
// Since the UWorld passed in might be null, as well as the NetDriver's UWorld,
// go through the world contexts until we find the one with this net driver.
for (auto& Context : WorldList)
{
if (Context.PendingNetGame != nullptr &&
Context.PendingNetGame->NetDriver == NetDriver &&
Context.OwningGameInstance != nullptr)
{
// Use the GameInstance from the current context.
Context.OwningGameInstance->HandleNetworkError(FailureType, bIsServer);
}
}
}
}

ENetworkFailure的声明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Runtime\Engine\Classes\Engine\EngineBaseType.h
/** Types of network failures broadcast from the engine */
UENUM(BlueprintType)
namespace ENetworkFailure
{
enum Type
{
/** A relevant net driver has already been created for this service */
NetDriverAlreadyExists,
/** The net driver creation failed */
NetDriverCreateFailure,
/** The net driver failed its Listen() call */
NetDriverListenFailure,
/** A connection to the net driver has been lost */
ConnectionLost,
/** A connection to the net driver has timed out */
ConnectionTimeout,
/** The net driver received an NMT_Failure message */
FailureReceived,
/** The client needs to upgrade their game */
OutdatedClient,
/** The server needs to upgrade their game */
OutdatedServer,
/** There was an error during connection to the game */
PendingConnectionFailure,
/** NetGuid mismatch */
NetGuidMismatch,
/** Network checksum mismatch */
NetChecksumMismatch
};
}

UE4:Max Agent

UE对AI支持的数量配置在Project Settings-Engine-Crowd Manager-Config-Max Agents,默认为50,在项目里出现的问题还以为是逻辑有问题,没想到还有这么个配置。

MakeRotFromXY

声明在UKismetMathSystemMakeRotFrom**函数的作用是,传递轴向(XY/YZ/YX等等)然后计算出从默认轴向(0,0,0)到该轴向的旋转。

UE4 Errpr:C1853 precompiled header file

在编译引擎时遇到以下错误:

1
fatal error C1853: 'C:\Program Files\Epic Games\UE_4.19\Engine\Intermediate\Build\Win64\UE4Editor\Development\Engine\SharedPCH.Engine.h.pch' precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa

解决办法:删掉该模块在Engine\Intermediate\Build\Win64下生成的文件夹,重新编译即可。

UE4 Error:C4577: 'noexcept' used

我在使用VS2017编译UE 4.18.3的时候编译器报了一个错误:

1
error C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc

这个错误是尝试使用异常,因为UE4默认情况下不允许使用异常,所以会产生这个错误。
解决的办法为,为报错的Module的build.cs中添加:

1
bEnableExceptions = true;

重新编译即可。

UE4 Error: error : '': Bad command or expression

检查一下报错的文件的编码格式:

改为UTF-8即可:

UE4:Break a C++ Struct in BP

在C++中新建一个USTRUCT结构,在蓝图中可以Break/Make需要有以下操作:

  1. 将USTRUCT标记为BlueprintType
  2. 对成员变量的UPROPERTY增加BlueprintReadWrite(EditAnyWhere并不控制是否可以Break)

UE4 Error:C4700: uninitialized local variable 'Parms' used

我在一个未实现的接口中返回自定义的结构类型会产生下列错误:

1
inetplayerstate.gen.cpp(36): error C4700: uninitialized local variable 'Parms' used

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// struct declare
#pragma once
#include "CoreMinimal.h"
#include "FClampData.generated.h"

USTRUCT(BlueprintType)
struct FClampData
{
GENERATED_USTRUCT_BODY()

UPROPERTY(BlueprintReadWrite)
bool bUseClamp;
UPROPERTY(BlueprintReadWrite)
int iMin;
UPROPERTY(BlueprintReadWrite)
int iMax;
};

使用的接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once
#include "Data/Struct/FClampData.h"
#include "CoreMinimal.h"
#include "INetPlayerState.generated.h"

// This class does not need to be modified.
UINTERFACE(BlueprintType, MinimalAPI)
class UINetPlayerState : public UInterface
{
GENERATED_BODY()
};

class SANGUOWARRIORS_API IINetPlayerState
{
GENERATED_BODY()

// Add interface functions to this class. This is the class that will be inherited to implement this interface.
public:
// ...
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
FClampData GetAssetClampData()const;
};

报错的位置在inetplayerstate.gen.cpp中,其代码为:

1
2
3
4
5
6
FClampData IINetPlayerState::GetAssetClampData() const
{
check(0 && "Do not directly call Event functions in Interfaces. Call Execute_GetAssetClampData instead.");
INetPlayerState_eventGetAssetClampData_Parms Parms;
return Parms.ReturnValue;
}

INetPlayerState_eventGetAssetClampData_Parms的定义为包裹返回值的结构:

1
2
3
4
5
#define SanguoWarriors_Source_SanguoWarriors_Public_Interface_GameFramework_INetPlayerState_h_15_EVENT_PARMS \
struct INetPlayerState_eventGetAssetClampData_Parms \
{ \
FClampData ReturnValue; \
};

根据之前的文章:关于编译器生成默认构造函数的一些误区,如果我们的结构FClampData没有提供默认构造函数,则INetPlayerState_eventGetAssetClampData_Parms这个结构也不会生成默认的构造函数,所以它的对象是没有初始化的。
所以,为了解决这个问题,我们对自己定义的USTRUCT结构定义一个默认构造函数就可以了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#pragma once
#include "CoreMinimal.h"
#include "FClampData.generated.h"

USTRUCT(BlueprintType)
struct FClampData
{
GENERATED_USTRUCT_BODY()
FORCEINLINE FClampData():bUseClamp(false),iMin(0),iMax(0){};
UPROPERTY(BlueprintReadWrite)
bool bUseClamp;
UPROPERTY(BlueprintReadWrite)
int iMin;
UPROPERTY(BlueprintReadWrite)
int iMax;
};

还有另一种更简单的方法是,把接口的返回值使用引用参数(暴露给蓝图的&参数会在蓝图节点的右侧,const&在左侧),不过这种方式对于C++的调用来说必须要传递一个实参:

1
2
UFUNCTION(BlueprintImplementableEvent, BlueprintCallable)
void GetAssetClampData(FClampData& rData)const;

引用本质也是指针来实现的。

UE4:GetPlayerController

UE的Player是以PlayerController为中心的,PlayerCharacter/PlayerPawn/PlayerCameraManager都是从PlayerController上获取的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// GameplayStatics.cpp
class APlayerController* UGameplayStatics::GetPlayerController(const UObject* WorldContextObject, int32 PlayerIndex )
{
if (UWorld* World = GEngine->GetWorldFromContextObject(WorldContextObject, EGetWorldErrorMode::LogAndReturnNull))
{
uint32 Index = 0;
for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
{
APlayerController* PlayerController = Iterator->Get();
if (Index == PlayerIndex)
{
return PlayerController;
}
Index++;
}
}
return nullptr;
}

ACharacter* UGameplayStatics::GetPlayerCharacter(const UObject* WorldContextObject, int32 PlayerIndex)
{
APlayerController* PC = GetPlayerController(WorldContextObject, PlayerIndex);
return PC ? Cast<ACharacter>(PC->GetPawn()) : nullptr;
}

APawn* UGameplayStatics::GetPlayerPawn(const UObject* WorldContextObject, int32 PlayerIndex)
{
APlayerController* PC = GetPlayerController(WorldContextObject, PlayerIndex);
return PC ? PC->GetPawnOrSpectator() : nullptr;
}

APlayerCameraManager* UGameplayStatics::GetPlayerCameraManager(const UObject* WorldContextObject, int32 PlayerIndex)
{
APlayerController* const PC = GetPlayerController(WorldContextObject, PlayerIndex);
return PC ? PC->PlayerCameraManager : nullptr;
}

UE:编辑器联机模式下退出崩溃

在编辑器中模拟联机的情况下退出后引擎崩溃,Log如下:

1
[2019.04.30-06.43.04:039][512]LogPlayLevel: Error: No PIE world was found when attempting to gather references after GC.

这是因为在关卡蓝图里调了RPC的事件,去掉即可。

UE4:联机游戏中AI不在视野被裁剪

在联机游戏如果怪物不在玩家的视野中,会被裁剪,其碰撞事件不会被触发,解决办法是将SkeletonMeshComponent的update骨架的配置改成always,就不会剪裁了。

UE:未包含CoreUObject.h的错误

相关链接:How to modify these errors in plugin?thanks

UE:C4668 Error '' is not defined as a prepeocessor macro

如果在UE中出现类似这样的错误:

1
error C4668: '__GUNC__' is not defined as a prepeocessor macro, replicing with '0' for '#if/#elif'

解决方案是在*.Build.cs文件里加上bEnableUndefinedIdentifierWarnings=false;(默认为true).
在UBT的代码中:

1
2
3
// Source\Programs\UnrealBuildTool\Configuration\ModuleRules.cs
// Enable warnings for using undefined identifiers in #if expressions
public bool bEnableUndefinedIdentifierWarnings = true;

通过它来控制是否在编译参数中加入/we4668:

1
2
3
4
5
6
7
8
9
10
11
12
// Source\Programs\UnrealBuildTool\Platform\Windows\VCToolChain.cs
if(WindowsPlatform.bUseVCCompilerArgs && CompileEnvironment.bEnableUndefinedIdentifierWarnings)
{
if (CompileEnvironment.bUndefinedIdentifierWarningsAsErrors)
{
Arguments.Add("/we4668");
}
else
{
Arguments.Add("/w44668");
}
}

UE:Detach Error in Net

这两天同事碰到这样一个同步问题:客户端抓取某样道具,使用AttachToComponent将其抓到手中,在丢弃时使用DetachFromComponent脱离。
在单机模式下毫无问题,但是涉及到网络同步时(UE的网络架构),有下面这样一个问题(为了测试我写了一个最简单的例子,使用最基础的C/S架构,完全由服务端处理(客户端只负责发起RPC调用和接收变量的同步)):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
LogOutputDevice: Error: === Handled ensure: ===
LogOutputDevice: Error: Ensure condition failed: !bRegistered || GetAttachParent()->GetAttachChildren().Contains(this) [File:D:\Build\++UE4+Release-4.18+Compile\Sync\Engine\Source\Runtime\Engine\Private\Components\SceneComponent.cpp] [Line: 2001]
LogOutputDevice: Error: Attempt to detach SceneComponent 'Cube' owned by 'Weapon_C_0' from AttachParent 'Scene' while not attached.
LogOutputDevice: Error: Stack:
LogOutputDevice: Error: [Callstack] 0x0000000006FB2786 UE4Editor-Core.dll!FWindowsPlatformStackWalk::StackWalkAndDump() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\private\windows\windowsplatformstackwalk.cpp:200]
LogOutputDevice: Error: [Callstack] 0x0000000006D5123A UE4Editor-Core.dll!FDebug::EnsureFailed() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\private\misc\assertionmacros.cpp:298]
LogOutputDevice: Error: [Callstack] 0x0000000006D6B906 UE4Editor-Core.dll!FDebug::OptionallyLogFormattedEnsureMessageReturningFalse() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\private\misc\assertionmacros.cpp:425]
LogOutputDevice: Error: [Callstack] 0x00000000DCB09BCF UE4Editor-Engine.dll!USceneComponent::DetachFromComponent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\components\scenecomponent.cpp:2001]
LogOutputDevice: Error: [Callstack] 0x00000000DCB20A19 UE4Editor-Engine.dll!USceneComponent::K2_DetachFromComponent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\components\scenecomponent.cpp:1987]
LogOutputDevice: Error: [Callstack] 0x00000000DC5615D0 UE4Editor-Engine.dll!USceneComponent::execK2_DetachFromComponent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\classes\components\scenecomponent.h:105]
LogOutputDevice: Error: [Callstack] 0x0000000006695264 UE4Editor-CoreUObject.dll!UFunction::Invoke() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4542]
LogOutputDevice: Error: [Callstack] 0x0000000006859B74 UE4Editor-CoreUObject.dll!UObject::CallFunction() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:732]
LogOutputDevice: Error: [Callstack] 0x000000000686FA41 UE4Editor-CoreUObject.dll!UObject::ProcessContextOpcode() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:2167]
LogOutputDevice: Error: [Callstack] 0x0000000006871B72 UE4Editor-CoreUObject.dll!UObject::ProcessInternal() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:954]
LogOutputDevice: Error: [Callstack] 0x0000000006695264 UE4Editor-CoreUObject.dll!UFunction::Invoke() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\class.cpp:4542]
LogOutputDevice: Error: [Callstack] 0x0000000006870F66 UE4Editor-CoreUObject.dll!UObject::ProcessEvent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\scriptcore.cpp:1314]
LogOutputDevice: Error: [Callstack] 0x00000000DC61E64B UE4Editor-Engine.dll!AActor::ProcessEvent() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\actor.cpp:693]
LogOutputDevice: Error: [Callstack] 0x00000000DD35AEDF UE4Editor-Engine.dll!FRepLayout::CallRepNotifies() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\replayout.cpp:2407]
LogOutputDevice: Error: [Callstack] 0x00000000DCBBE6AB UE4Editor-Engine.dll!FObjectReplicator::CallRepNotifies() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datareplication.cpp:1474]
LogOutputDevice: Error: [Callstack] 0x00000000DCBE84BF UE4Editor-Engine.dll!FObjectReplicator::PostReceivedBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datareplication.cpp:1032]
LogOutputDevice: Error: [Callstack] 0x00000000DCBEB549 UE4Editor-Engine.dll!UActorChannel::ProcessBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:2297]
LogOutputDevice: Error: [Callstack] 0x00000000DCBF902C UE4Editor-Engine.dll!UActorChannel::ReceivedBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:2139]
LogOutputDevice: Error: [Callstack] 0x00000000DCBFD75C UE4Editor-Engine.dll!UChannel::ReceivedSequencedBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:296]
LogOutputDevice: Error: [Callstack] 0x00000000DCBFC6AE UE4Editor-Engine.dll!UChannel::ReceivedNextBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:665]
LogOutputDevice: Error: [Callstack] 0x00000000DCBFD4C5 UE4Editor-Engine.dll!UChannel::ReceivedRawBunch() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\datachannel.cpp:388]
LogOutputDevice: Error: [Callstack] 0x00000000DD0E23A6 UE4Editor-Engine.dll!UNetConnection::ReceivedPacket() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\netconnection.cpp:1319]
LogOutputDevice: Error: [Callstack] 0x00000000DD0E3602 UE4Editor-Engine.dll!UNetConnection::ReceivedRawPacket() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\netconnection.cpp:728]
LogOutputDevice: Error: [Callstack] 0x00000000D6F1A2E3 UE4Editor-OnlineSubsystemUtils.dll!UIpNetDriver::TickDispatch() [d:\build\++ue4+release-4.18+compile\sync\engine\plugins\online\onlinesubsystemutils\source\onlinesubsystemutils\private\ipnetdriver.cpp:232]
LogOutputDevice: Error: [Callstack] 0x00000000DD0C065F UE4Editor-Engine.dll!TBaseUObjectMethodDelegateInstance<0,UNetDriver,void __cdecl(float)>::ExecuteIfSafe() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\public\delegates\delegateinstancesimpl.h:858]
LogOutputDevice: Error: [Callstack] 0x00000000DC51CF78 UE4Editor-Engine.dll!TBaseMulticastDelegate<void,float>::Broadcast() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\public\delegates\delegatesignatureimpl.inl:937]
LogOutputDevice: Error: [Callstack] 0x00000000DCF653F8 UE4Editor-Engine.dll!UWorld::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\engine\private\leveltick.cpp:1296]
LogOutputDevice: Error: [Callstack] 0x00000000FE7D6BA6 UE4Editor-UnrealEd.dll!UEditorEngine::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:1659]
LogOutputDevice: Error: [Callstack] 0x00000000FF084AC6 UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:396]
LogOutputDevice: Error: [Callstack] 0x0000000035025A26 UE4Editor.exe!FEngineLoop::Tick() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:3296]
LogOutputDevice: Error: [Callstack] 0x0000000035035430 UE4Editor.exe!GuardedMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launch.cpp:166]
LogOutputDevice: Error: [Callstack] 0x00000000350354AA UE4Editor.exe!GuardedMainWrapper() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
LogOutputDevice: Error: [Callstack] 0x0000000035042379 UE4Editor.exe!WinMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:210]
LogOutputDevice: Error: [Callstack] 0x0000000035043D57 UE4Editor.exe!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253]
LogOutputDevice: Error: [Callstack] 0x0000000045863DC4 KERNEL32.DLL!UnknownFunction []
LogOutputDevice: Error: [Callstack] 0x0000000045D63691 ntdll.dll!UnknownFunction []

这是由于Attch组件自身和Attach ParentComponent Replication被设置了,然后在从Server收到的变量同步事件OnRep_中再做Detach操作就会触发。
其实问题一句话可以概括:将自己从AttachParent上Detach掉,会判断将要Detach父级的AttachChildren列表中判断自己存不存在,这个断言触发的是,自己的父级存在(Parent!=nullptr),但是父级对象的AttachChildren中不包含自己。
其实在C/S架构中,C端应该只做表现,而不处理逻辑,出现上面的问题也是联机模式下的实现思路问题,因为UE的Attach和Detach是会同步的,具体细节先按下不表,后续我会从代码分析一下这个问题。

UE Package:Couldn't save package,filename is too long

在打包的时候遇到这个错误,是因为某些资源在Windows上的绝对路径长度超过了260个字符,这是NTFS的限制。
所以,将项目路径移动到磁盘根目录,或者减少目录层级即可。
引擎中相关的代码在:

1
2
3
4
5
6
7
8
9
10
11
// Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp(UE4.18.3)
// need to subtract 32 because the SavePackage code creates temporary files with longer file names then the one we provide
// projects may ignore this restriction if desired
const int32 CompressedPackageFileLengthRequirement = bConsiderCompressedPackageFileLengthRequirements ? 32 : 0;
const FString FullFilename = FPaths::ConvertRelativePathToFull(PlatFilename);
if (FullFilename.Len() >= (PLATFORM_MAX_FILEPATH_LENGTH - CompressedPackageFileLengthRequirement))
{
LogCookerMessage(FString::Printf(TEXT("Couldn't save package, filename is too long: %s"), *PlatFilename), EMessageSeverity::Error);
UE_LOG(LogCook, Error, TEXT("Couldn't save package, filename is too long :%s"), *PlatFilename);
Result = ESavePackageResult::Error;
}

而各个平台的PLATFORM_MAX_FILEPATH_LENGTH均定义在Runtime/Core/Public相关的平台下。
Windows是使用的另一个宏WINDOWS_MAX_PATH

1
2
3
4
5
6
D:\UnrealEngine\Offical_Source\4.18\Engine\Source\Runtime\Core\Public\Windows\WIndowsPlatform.h:
57 #define PLATFORM_HAS_BSD_TIME 0
58 #define PLATFORM_USE_PTHREADS 0
59: #define PLATFORM_MAX_FILEPATH_LENGTH WINDOWS_MAX_PATH
60 #define PLATFORM_HAS_BSD_SOCKET_FEATURE_WINSOCKETS 1
61 #define PLATFORM_USES_MICROSOFT_LIBC_FUNCTIONS 1

WINDOWS_MAX_PATH这个宏定义在Runtime/Core/Private/Windows/MinimalWindowsApi.h中:

1
#define WINDOWS_MAX_PATH 260

显然UE并没有使用Windows提供的MAX_PATH宏,硬编码为了260,即在UE中Windows上的文件路径最大长度为260个字符(在启用bConsiderCompressedPackageFileLengthRequirements时还要减去32个字符),虽然Windows10要移除260字符的限制,~但是貌似UE没有跟进的打算~(UE4.22 Released支持了长文件名的特性(实验性))。
bConsiderCompressedPackageFileLengthRequirements选项可以加在Saved/Config/Windows/Engine.ini下(默认为true):

1
2
[CookSettings]
bConsiderCompressedPackageFileLengthRequirements = true

这个配置是在Cook时会被加载用来判断是否考虑引擎生成的文件名长度:

1
2
3
4
5
6
7
8
// Source/Editor/UnrealEd/Private/CookOnTheFlyServer.cpp(UE4.18.3)
// need to subtract 32 because the SavePackage code creates temporary files with longer file names then the one we provide
bool UCookOnTheFlyServer::ShouldConsiderCompressedPackageFileLengthRequirements() const
{
bool bConsiderCompressedPackageFileLengthRequirements = true;
GConfig->GetBool(TEXT("CookSettings"), TEXT("bConsiderCompressedPackageFileLengthRequirements"), bConsiderCompressedPackageFileLengthRequirements, GEditorIni);
return bConsiderCompressedPackageFileLengthRequirements;
}

UCookOnTheFlyServer::SaveCookedPackage中需要通过它来决定将系统支持的MAX_PATH减去32之后的结果,用来判断资源路径是否超出限制。

外部阅读:

UE开启多重采样和前向渲染

ProjectSetting-Rendering-ForwardRenderer/DefaultSetting-Anti-Aliasing Method

UE4 Plugin:ModuleType(Required)

.uplugin Module Type Descriptors.

Sets the type of Module. Valid options are Runtime, RuntimeNoCommandlet, Developer, Editor, EditorNoCommandlet, and Program. This type determines which types of applications this Plugin's Module is suitable for loading in. For example, some plugins may include modules that are only designed to be loaded when the editor is running. Runtime modules will be loaded in all cases, even in shipped games. Developer modules will only be loaded in development runtime or editor builds, but never in shipping builds. Editor modules will only be loaded when the editor is starting up. Your Plugin can use a combination of modules of different types.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// Engine\Programs\UnrealBuildTool\System\ModuleDescriptor.cs
// The type of host that can load a module
public enum ModuleHostType
{
Default,

// Any target using the UE4 runtime
Runtime,

// Any target except for commandlet
RuntimeNoCommandlet,

// Any target or program
RuntimeAndProgram,

// Loaded only in cooked builds
CookedOnly,

// Loaded only when the engine has support for developer tools enabled
Developer,

// Loaded only by the editor
Editor,

// Loaded only by the editor, except when running commandlets
EditorNoCommandlet,

// Loaded only by programs
Program,

// Loaded only by servers
ServerOnly,

// Loaded only by clients
ClientOnly,
}

UE4 Plugin:LoadingPhase(Optional)

.uplugin Module LoadingPhase Descriptors.

If specified, controls when the plugin is loaded at start-up. This is an advanced option that should not normally be required. The valid options are Default(which is used when no LoadingPhase is specified), PreDefault, and PostConfigInit. PostConfigInit enables the module to be loaded before the engine has finished starting up key subsystems. PreDefault loads just before the normal phase. Typically, this is only needed if you expect game modules to depend directly on content within your plugin, or types declared within the plugin's code.

如果.upugin中没有指定LoadingPhase项,则默认是Default:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Engine\Programs\UnrealBuildTool\System\ModuleDescriptor.cs
// Indicates when the engine should attempt to load this module
public enum ModuleLoadingPhase
{
/// Loaded at the default loading point during startup (during engine init, after game modules are loaded.)
Default,

// Right after the default phase
PostDefault,

// Right before the default phase
PreDefault,

// Loaded before the engine is fully initialized, immediately after the config system has been initialized. Necessary only for very low-level hooks
PostConfigInit,

// After PostConfigInit and before coreUobject initialized. used for early boot loading screens before the uobjects are initialized
PreEarlyLoadingScreen, // Since 4.20

// Loaded before the engine is fully initialized for modules that need to hook into the loading screen before it triggers
PreLoadingScreen,

// After the engine has been initialized
PostEngineInit,

// Do not automatically load this module
None,
}

GENERATED_BODY和GENERATED_UCLASS_BODY的区别

GENERATED_BODY:

  • 不包含任何访问标识符,class默认是privatestruct默认是public.
  • 没有声明任何构造函数(constructor)

GENERATED_UCLASS_BODY:

  • 包含public访问标识符
  • 具有一个构造函数的声明,其参数为const FObjectInieializer&:
1
2
3
4
5
6
7
8
9
10
11
12
// .h file
// ...
GENERATED_BODY()

public:
AFPSGameMode(const class FObjectInitializer& ObjectInitializer);

// .cpp file
AFPSGameMode::AFPSGameMode(const class FObjectInitializer& ObjectInitializer)
{
// constructor functionality
}

参考链接:GENERATED_BODY vs GENERATED_UCLASS_BODY

Extensibility in UE4

UE4 Slate UI Framedowk

Networking in UE4

UE4 Engine Overview

Epic's Build Tools & Infrastructure

UHT的宏定义

GENERATED_BODY以及UPROPERTYUFUNCTION等宏的定义均是在:

1
Engine\Source\Runtime\CoreUObject\Public\UObject\ObjectMacros.h

UE Build:MakeShareable no matching

如果我们将一个类为T的C++原生指针通过MakeShareable的方式创建一个FRawPtrProxy<T>然后用来构造一个TSharedPtr<t>,有时会产生下列错误:

1
2
3
4
Engine\Source\Programs\UE4Launcher\Source\Private\UI\WidgetUELauncher.cpp(620): error C2672: 'MakeShareable': no matching overloaded function found
Engine\Source\Programs\UE4Launcher\Source\Private\UI\WidgetUELauncher.cpp(620): error C2780: 'SharedPointerInternals::FRawPtrProxy<ObjectType> MakeShareable(ObjectType *,DeleterType &&)': expects 2 arguments - 1 provided
Engine\Source\Runtime\Core\Public\Templates/SharedPointer.h(1666): note: see declaration of 'MakeShareable'
Engine\Source\Programs\UE4Launcher\Source\Private\UI\WidgetUELauncher.cpp(620): error C2784: 'SharedPointerInternals::FRawPtrProxy<ObjectType> MakeShareable(ObjectType *)': could not deduce template argument for 'ObjectType *' from 'TSharedRef<ObjectType,0>'

这是因为类型T的析构函数访问权限设置了保护,而这些引用计数的智能指针在计数为0时就会调用该对象的析构函数,所以会出现编译错误。
如果必须要创建一个TSharedPtr<T>,如果T为自己创建的SWidget派生类,可以把struct SharedPointerInternals::FRawPtrProxy<T>设置为友元(Makeshareable()就是构造了这个对象):

1
2
// SEditableBoxWraper is a custom Widget derived by SWidget 
friend struct SharedPointerInternals::FRawPtrProxy<SEditableBoxWraper>;

UE Package:Create a patch

最需要注意的是下面三点:
You can patch a project you have previously released using a versioned release. Some things to keep in mind are:

  • Lock down the serialization code paths at the time of release.
  • Keep the released cooked content, as the UnrealPak tool uses this to determine which content should be in the patch package file.
  • At runtime, mount both pak files, with a higher priority for the patch file so any content within it is loaded first.

总结来说就是,要保证与上次打包的资源路径不变/保留上次打包版本的Saved/Cooked目录(因为创建的Patch是通过UnrealPak来检测当前项目里的资源与上次Cooked的差异),程序运行时优先加载Patch的文件*0_P.pak,其中数字越大加载的优先级越高。

蓝图的功能实现也是uasset的,所以也会打包在pak里面,而不会在.exe里。蓝图是运行在虚拟机上的(详见Blueprint FAQ and Tips),并不是类似C++的直接编译成二进制文件,即蓝图也是资源,所以会打包在pak里面,这意味着如果纯用蓝图实现的项目可以不用变动.exe只增加patch就可以达到游戏更新。

UE在编辑器内点Compile时自动保存资源

UE运行时动态更新寻路

UE EditorModule在Standalone下不会加载

注意:Module的Type如果为Editor则在Standalone下是不加载的。会出现在编辑器模式下是正常的,但是在Standalone运行时没有任何效果,新建的插件最好以Developer或者Runtime。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "TaskTools",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"Installed": false,
"Modules": [
{
"Name": "TaskTools",
"Type": "Developer",
"LoadingPhase": "Default"
}
]
}

UE版本号的宏定义

引擎中标记引擎版本的宏:

  • ENGINE_MAJOR_VERSION
  • ENGINE_MINOR_VERSION
  • ENGINE_PATCH_VERSION

等,是在Engine/Source/Runtime/Launch/Resources/Version.h中定义:

1
2
3
4
5
// These numbers define the banner UE4 version, and are the most significant numbers when ordering two engine versions (that is, a 4.12.* version is always 
// newer than a 4.11.* version, regardless of the changelist that it was built with)
#define ENGINE_MAJOR_VERSION 4
#define ENGINE_MINOR_VERSION 19
#define ENGINE_PATCH_VERSION 0

引擎的版本信息也记录在Engine\Build\Build.version文件中:

1
2
3
4
5
6
7
8
9
10
{
"MajorVersion": 4,
"MinorVersion": 18,
"PatchVersion": 3,
"Changelist": 0,
"CompatibleChangelist": 3709383,
"IsLicenseeVersion": 0,
"IsPromotedBuild": 1,
"BranchName": ""
}

UE蓝图的循环迭代最大计数

UE蓝图里面的循环上限是需要在ProjectSetting-Engine-Blueprints里设置(默认是1000000):

UE:Primary Asset Id

先在Project Setting-Game-Asset Manager里添加资源路径:

然后就可以在蓝图的PrimaryAssetId中选择了:

UE Package Error: noexcept

如果打包时遇到下列错误:

1
C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc

*.target.cs中添加:

1
bForceEnableExceptions = true;

即可。

UE Package: Create Compressed Cooked Packages

打包时压缩pak:

UE Package:Use Log in Shipping

在我之前的文章Macro defined by UBT in UE4#USE_LOGGING_IN_SHIPPING中写道,可以在Module的*.target.cs中使用bUseLoggingInShipping来控制打包模式为Shipping的包是否启用日志。
注意:目前只支持源码版引擎,如果在Launcher安装的Engine会报链接错误:

1
error LNK2001: unresolved external symbol "struct FLogCategoryLogSerialization LogSerialization" (?LogSerialization@@3UFLogCategoryLogSerialization@@A)

同时,如果出现下列错误:

1
C4577: 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc

则在*.target.cs中添加:

1
bForceEnableExceptions = true;

即可。

UE创建StandaloneApplication

使用UE也可以写应用程序(StandaloneApplication: Target is Program),可以把UE当作一个超大的ThridParty.
我写了一个模板:hxhb/UEProgramTemplate.
运行效果:

但是想要创建新的StandaloneApplication太麻烦了,我写了一个小工具可以直接创建:hxhb/UECreateProgramTemplateTool.

1
2
3
# Usage
$ create_program.exe $ProgramName
Create Standalone Program Successed!
  1. move $ProgramName Folder to Engine\Source\Programs (version of source code)
  2. run GenerateProgramProject.bat
  3. OpenProgramProject.bat

用起来相当酸爽。

注意
*.target.cs中的配置会影响UBT生成的一些宏定义,比如:

  • bBuildWithEditorOnlyData控制的是WITH_EDITORONLY_DATA
  • bCompileAgainstEngine控制的是WITH_ENGINE

开发Program类型的程序时需要注意这些配置。可以在UnrealBuildSystem/Targets查看*.target.cs支持的全部参数。
UBT的代码里解析*.Target.cs里的配置在Programs\UnrealBuildTools\Configuration\URBuildTarget.csSetupGlobalEnvironment函数。

##UE4 Package: LogLinker Error: xxxx has an inappropriate outermos
在打包时遇到以下错误:

1
2
3
4
5
UATHelper: Packaging (Windows (64-bit)):   LogLinker: Error: HOTRELOADED_INetGameMode_1 has an inappropriate outermost, it was probably saved with a deprecated outer (file: ../../../../../../SanguoWarriors/Content/CoreBP/GamePlayFramework/GameMode/Net_GameMode_VR_Ex.uasset)
UATHelper: Packaging (Windows (64-bit)): LogLinker: Error: HOTRELOADED_INetGameMode_1 has an inappropriate outermost, it was probably saved with a deprecated outer (file: ../../../../../../SanguoWarriors/Content/CoreBP/GamePlayFramework/GameMode/Net_GameMode_VR_Ex.uasset)
UATHelper: Packaging (Windows (64-bit)): LogLinker: Error: HOTRELOADED_INetGameMode_1 has an inappropriate outermost, it was probably saved with a deprecated outer (file: ../../../../../../SanguoWarriors/Content/CoreBP/GamePlayFramework/GameMode/Net_GameMode_VR_Ex.uasset)
UATHelper: Packaging (Windows (64-bit)): LogLinker: Error: HOTRELOADED_INetGameMode_1 has an inappropriate outermost, it was probably saved with a deprecated outer (file: ../../../../../../SanguoWarriors/Content/CoreBP/GamePlayFramework/GameMode/Net_GameMode_VR_Ex.uasset)
UATHelper: Packaging (Windows (64-bit)): LogLinker: Error: HOTRELOADED_INetGameMode_1 has an inappropriate outermost, it was probably saved with a deprecated outer (file: ../../../../../../SanguoWarriors/Content/CoreBP/GamePlayFramework/GameMode/Net_GameMode_VR_Ex.uasset)

这是该资源引用了一些无效的资源:

解决办法是,随便在蓝图内修改一点东西,点保存编译即可。
最后再打开它的Reference Viewer确定没有无效资源即可。

UE4 Package:FMemoryWriter does not support data larger than 2GB. Archive name: None.

打包时出现了这个错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
UATHelper: Packaging (Windows (64-bit)):   LogWindows: Error: begin: stack for UAT
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: === Critical error: ===
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error:
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: Fatal error: [File:D:\Build\++UE4+Release-4.18+Compile\Sync\Engine\Source\Runtime\Core\Public\Serialization/MemoryWriter.h] [Line: 42]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: FMemoryWriter does not support data larger than 2GB. Archive name: None.
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error:
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error:
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000EB1AA388 KERNELBASE.dll!UnknownFunction []
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000D87676D4 UE4Editor-ApplicationCore.dll!FWindowsErrorOutputDevice::Serialize() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\applicationcore\private\windows\windowserroroutputdevice.cpp:65]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C1BA330B UE4Editor-Core.dll!FOutputDevice::Logf__VA() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\private\misc\outputdevice.cpp:70]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C1B347F9 UE4Editor-Core.dll!FDebug::AssertFailed() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\private\misc\assertionmacros.cpp:414]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000BD417374 UE4Editor-CoreUObject.dll!FMemoryWriter::Serialize() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\core\public\serialization\memorywriter.h:42]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000BD510857 UE4Editor-CoreUObject.dll!FUntypedBulkData::SerializeBulkData() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\serialization\bulkdata.cpp:1253]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000BD647A5C UE4Editor-CoreUObject.dll!UPackage::Save() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\coreuobject\private\uobject\savepackage.cpp:5122]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5F0EB8D UE4Editor-UnrealEd.dll!UEditorEngine::Save() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:4220]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5DD112E UE4Editor-UnrealEd.dll!UCookOnTheFlyServer::SaveCookedPackage() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\cookontheflyserver.cpp:3229]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5DD2473 UE4Editor-UnrealEd.dll!UCookOnTheFlyServer::SaveCookedPackages() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\cookontheflyserver.cpp:2300]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5DDE3B7 UE4Editor-UnrealEd.dll!UCookOnTheFlyServer::TickCookOnTheSide() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\cookontheflyserver.cpp:1763]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5C77D61 UE4Editor-UnrealEd.dll!UCookCommandlet::CookByTheBook() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\commandlets\cookcommandlet.cpp:902]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000B5C9F391 UE4Editor-UnrealEd.dll!UCookCommandlet::Main() [d:\build\++ue4+release-4.18+compile\sync\engine\source\editor\unrealed\private\commandlets\cookcommandlet.cpp:583]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C5E0D25F UE4Editor-Cmd.exe!FEngineLoop::PreInit() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:2167]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C5E0525A UE4Editor-Cmd.exe!GuardedMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\launch.cpp:127]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C5E054AA UE4Editor-Cmd.exe!GuardedMainWrapper() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:134]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C5E12379 UE4Editor-Cmd.exe!WinMain() [d:\build\++ue4+release-4.18+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:210]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000C5E13193 UE4Editor-Cmd.exe!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:253]
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000EB954034 KERNEL32.DLL!UnknownFunction []
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000EE083691 ntdll.dll!UnknownFunction []
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: [Callstack] 0x00000000EE083691 ntdll.dll!UnknownFunction []
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error:
UATHelper: Packaging (Windows (64-bit)): LogWindows: Error: end: stack for UAT

这是因为场景的烘培文件大于了2G,而UE的FMemoryWriter最大支持2G的文件,所以需要更改场景的光照参数(PackedLightAndShadowMapTextureSize或者将场景拆分为多个子关卡,保证烘焙之后每个子关卡的*_BuildData.uasset小于2G)。

UE Crash:破碎组件(DestructibleMesh)导致的崩溃

在最近的使用中,在服务端创建出来的DestructibleMesh,破碎之后再服务端销毁,在客户端会崩溃,不销毁只是破碎后隐藏就不会Crash,这在UE4.18.3上存在这个问题,先记录一下,有时间再深度研究一下。

未完待续。
本文标题:UE4开发的问题笔记和资料辑录
文章作者:ZhaLiPeng
发布时间:2019年05月27日 22时07分
本文字数:本文一共有7.6k字
原始链接:https://imzlp.me/posts/25331/
许可协议: CC BY-NC-SA 4.0
转载请保留原文链接及作者信息,谢谢!
您的捐赠将鼓励我继续创作!