ue 使用中注意的问题(持续更新)

1.ue4中使用try catch时,应该在在模块的build.cs中,加入bEnableExceptions = true;不然打包会出错

2.包含第三方库时,有可能出现预处理器没有定义的情况,在库的头文件中使用预处理器进行某些判断时,会报错,解决方法:这时,在模块的build.cs中,加入bEnableUndefinedIdentifierWarnings = false;

3.包含某些外部库头文件产生:没有将“_WIN32_WINNT_WIN10_TH2”定义为预处理器宏,用“0”替换“#if/#elif 解决方法:在头文件前加入: #define WIN32_LEAN_AND_MEAN

4.boost库使用时,需要加入预定义以及取消未定义宏警告

PublicDefinitions.AddRange(new string[] { "BOOST_DISABLE_ABI_HEADERS" });

bEnableUndefinedIdentifierWarnings = false;

5.UE4 中将某些编译警告信息当成了错误,可以在对应文件中加入如下信息将错误转回警告

#pragma warning(push)//将当前警告信息入栈存储起来

#pragma warning(default:4018)//这里的4018是错误编号

你的code

#pragma warning(pop)//将栈顶存储的警告信息覆盖现在的警告信息

6.打包时如果有UE_Log输出为error类型,会打包出错。

7.插件的打包问题:

必须使用c++工程,且用到的 插件模块 的类型必须为runtime。

https://docs.unrealengine.com/zh-CN/Programming/Plugins/index.html

8.UE4 debug时查看变量,变量显示variable is optimized away and not available。

解决方法: 在想要查看变量得函数前后分别加 #pragma optimize("",off)  和 #pragma optimize("",on) 

9. USkeletalMeshComponent的 SetAnimationInstanceClass 以及 SetAnimationMode 方法,蓝图中使用会crash,解决方法是在使用前先重置一下SkeletalMesh(SetSkeletalMesh)

10.ue4 c++ 的FRotator 传参是 y(pitch),z(yaw),x(roll),  不是xyz(巨坑)

11.蓝图类资源也可以通过LoadObject加载或Assetdata的loadasset加载,但是只有在编辑器模式下才会加载成功。加载后可通过object->GeneratedClass,获得对应的类型(也就是_C后缀的类名称)。

12.设置鼠标样式或是显示与否时,会出现没有立即刷新,需要移动鼠标的情况,可以使用下面的代码立即刷新鼠标

  1. auto& App = FSlateApplication::Get();

  2. App.QueryCursor(); //This line is refreshing the cursor (it executes fake mouse event for each platform).

13.unpossess后没有possess,那么会在一帧后重设targetview为playercontroller。所以会出现unpossess后跟settargetview无效的情况。可以延迟一帧后设置settargetview

14.插件的代码重新编译不支持代码的热加载

15. 异步加载资源在没有指定开启多线程加载时,是在游戏线程中进行的请先确保异步加载线程已经启用,否则异步加载是有可能在游戏线程(主线程)分时加载的。 在项目设置,Streaming分页中,确保Async Loading Thread Enabled打开。或者在DefaultEngine.ini的[/Script/Engine.StreamingSettings]内加上s.AsyncLoadingThreadEnabled=True。或者,在你的游戏进程/编辑器启动进程加上参数-AsyncLoadingThread。 编辑器模式,以及编辑器的standalone模式下多线程加载无法启用。

16.注意:资源没有被引用时,会标记为回收,回收时间大概是几秒到几分钟。你也可以使用GEngine->ForceGarbageCollection(true);强制立即回收。

17.

BindUObject代理的多线程使用: BindUObject looks thread-unsafe? - UE4 AnswerHub

BindUObject,在多线程中使用时,会有问题,比如在其他线程中调用BroadCast时,代理的绑定会被自动remove。

当调用代理的BroadCast时,BroadCast会去执行每个绑定对象的ExecuteIfSafe。对于BindUObject,该函数首先检测对应的UObject是否能够Get到。该UObject存储在TWeakObjectPtr中, Get方法中将首先获取存储在GUObjectArray中的FObjectItem。如果ObjectItem是null或者检测到ObjectItem是UnReachable时,则Get将返回null。 在主线程中,这不会有什么问题,只要UObject对象是有引用的或者已经加入根集,Get都不会返回null。但在其他线程中,就会出问题,在GC时,会调用MarkObjectsAsUnreachable,在该函数中,不在根集中的ObjectItem会调用ObjectItem->SetFlags(EInternalObjectFlags::Unreachable),将对象标记为unReachable。 然后在PerformReachabilityAnalysisOnObjects 函数中,会将ObjectItem重新设置为正确的值。在这个过程中,如果其他线程调用TWeakObjectPtr的get方法,就会返回null。BindUObject的 ExecuteIfSafe 检测到get返回null时,ExecuteIfSafe 将返回false,然后BroadCast函数将清除那些不可用的绑定对象,也就造成了在其他线程代理会自动移除绑定。

解决方法是使用BindLambda 包一下 Uobject的方法调用:

handler = UAudioReceiveThread::AddListen(FAudiomdReceiveDelegate::FDelegate::CreateUObject(this, &UMocapAudioComponent::ReceiveRes));

将上面的代码替换为下面的:

handler = UAudioReceiveThread::AddListen(FAudiomdReceiveDelegate::FDelegate::CreateLambda([&](const uint8 * Buf, int SampleNums) {

       this->ReceiveRes(Buf, SampleNums);

}));

18.骨架网格体要按网格体复杂碰撞,需要同时开启mesh的 enable per poly collison和骨架网格体组件的enable per poly collison

19.

最常用的两个全局的Delegate对象:

FCoreUObjectDelegates

FCoreDelegates

20.

常用曲线的数值计算

动画融合常用曲线计算

21.EditorUtilityWidgetBlueprint,在编辑器中执行时,不会执行OnInitialized()事件;

22.

纹理流送遇到的问题:
在材质中贴图使用为 负值的mip偏移的话,会导致流送的的mip无法使用正确的mip层级.因为流送仅会流送小于等于不设偏移mip的纹理尺寸。(既如果贴图默认使用尺寸为1024,则流送导致显存中最高只存储有1024尺寸。 而设置偏移后要使用4096,流送还是只流送最高1024尺寸
这时,需要将对应的贴图设置为不流送(Never Stream)才可以。
贴图的LodBias设为负值仅用于修正其组的LodBias。 LODBias +Texture的组LodBias 介于0与最大mip层级之间 。贴图的LodBias仅影响最高可用mip。不影响材质中贴图的实际Bias偏移。
贴图的非过场动画偏移Bias计算位于 UTexture :: UpdateCachedLODBias中,
void UTexture::UpdateCachedLODBias()
{
       CachedCombinedLODBias =  UDeviceProfileManager::Get().GetActiveProfile()->GetTextureLODSettings()->CalculateLODBias(this);
}
以下最主要部分:
       // Calculate LOD bias.
       int32 UsedLODBias    = NumCinematicMipLevels;
       if (!FPlatformProperties::RequiresCookedData())
       {
              // When cooking, LODBias and LODGroupInfo.LODBias are taken into  account to strip the top mips.
              // Considering them again here would apply them twice.
              UsedLODBias   += LODBias + LODGroupInfo.LODBias;
       }
       
       if (LODGroup == TEXTUREGROUP_UI)
       {
              UsedLODBias += GUITextureLODBias;
       }
       int32 MinLOD         = LODGroupInfo.MinLODMipCount;
       int32 MaxLOD         = LODGroupInfo.MaxLODMipCount;
       int32 WantedMaxLOD   = FMath::Clamp( TextureMaxLOD - UsedLODBias, MinLOD,  MaxLOD );
       WantedMaxLOD         = FMath::Clamp( WantedMaxLOD, 0, TextureMaxLOD );
       UsedLODBias                = TextureMaxLOD - WantedMaxLOD;
       return UsedLODBias;
对于打包为烘焙资源的游戏包,将从资源本体中剔除Texture的 LODBias +Texture的组LodBias 级mip。
然后不管是否剔除,实际游戏中使用的层级都为剔除完 LODBias +Texture的组LodBias 后的 剩余部分,然后 NumCinematicMipLevels决定了在剔除完后,剩余部分的前面的多少级为影片模式下使用的mip,所以最后游戏非影片模式下可以使用的总mips数为:
最大mip数 - ( LODBias +Texture的组LodBias + NumCinematicMipLevels )。
其中 LODBias +Texture的组LodBias )介于0与 最大mip层级之间。
texture2d在创建FTexture2DResource时,会创建一个 FStreamableRenderResourceState,该结构体指示了流送的信息,
包括是否支持流送 bSupportsStreaming
最多包含的mip层级 MaxNumLODs 最大mip数 - (LODBias +Texture的组LodBias) ),
需要流送的mip数量 NumRequestedLODs等信息(默认流送大概是7级mip)
FTextureResource* UTexture2D::CreateResource()
{
    。。。。。
                         const FStreamableRenderResourceState PostInitState =  GetResourcePostInitState(PlatformData, !bTemporarilyDisableStreaming, ResourceMem  ? ResourceMem->GetNumMips() : 0, NumMips);
                     FTexture2DResource* Texture2DResource = new  FTexture2DResource(this, PostInitState);
    。。。。
}

23.

PlayMontage这个函数数 的Noify ,值支持继承自Motage Noify 的事件,其他事件不支持。

24.

添加额外的log记录方法:( 最好是在 FGenericPlatformOutputDevices:: SetupOutputDevices中添加)
1.修改默认Log位置(该方法最好在 FGenericPlatformOutputDevices:: GetLog 中直接修改 ):
#include "HAL/PlatformOutputDevices.h"
#include "Misc/OutputDeviceFile.h"
        FOutputDeviceFile* OutputDevice = static_cast< FOutputDeviceFile *>( FPlatformOutputDevices:: GetLog());
        if ( OutputDevice) {
               OutputDevice-> SetFilename( TEXT( "C:/BulidPlugins/BuildPlugins_4_25/Saved/1.txt"));
       }
该方法在其他地方添加的劣势是,无法全部获得全部的log。
2.添加新的Log记录方法:
static TUniquePtr < FOutputDeviceFile > OutputDeviceFile ( new FOutputDeviceFile ( TEXT ( "C:/BulidPlugins/BuildPlugins_4_25/Saved/2.txt" )));
GLog -> AddOutputDevice ( OutputDeviceFile . Get ());
用完以后要删除
GLog -> RemoveOutputDevice( OutputDeviceFile . Get () );
3.在启动时添加命令行参数  logcategoryfiles(具体查看 FGenericPlatformOutputDevices:: GetPerChannelFileOverrides
logcategoryfiles= C:/BulidPlugins/BuildPlugins_4_25/Saved/2.txt=LogTemp +  C:/BulidPlugins/BuildPlugins_4_25/Saved/3.txt=
2.txt 只存储LogTemp类型的日志,  3.txt存储所有类型的日志。(注意:=必须带)
25.
添加c++崩溃日志记录:
在派生自UObject的对象中,override  ShutdownAfterError , 全局变量 GErrorHist 中包含崩溃堆栈
void USequenceTaskEditorSubsystem:: ShutdownAfterError ()
{
      FFileHelper::SaveStringToFile( GErrorHist ,  TEXT("C:/BulidPlugins/BuildPlugins_4_25/Saved/1.txt"));
}
26.

为控制台添加可执行程序: 在UFUNCTION中添加Exec

    UFUNCTION(Exec)

    static void StartPerformanceSnapshots();

注意,并不是所有的类都支持加入Exec指令,只有Possessed Pawns(拥有操控权pawn), Player Controllers,Player Input, Cheat Managers, Game Modes, Game Instances, 引擎重写类, HUD。

但可以单独添加执行的控制台指令,参考EngineGlobals.cpp下的:

static FAutoConsoleCommand GShowWidgetReflector

(

    TEXT("WidgetReflector"),

    TEXT("Displays the Slate widget reflector"),

    FConsoleCommandDelegate::CreateStatic(ShowWidgetReflector)

);

27.

设置声音启用混响以及窗口失去焦点后窗口声音的大小(默认为0)

在 DefaultEngine.ini 中的[Audio]中添加以下内容:

[Audio]

UnfocusedVolumeMultiplier=1.0

二维平面内,在圆内均匀分布:

三维空间内,在球内均匀分布:

28.

要取消-game 模式中的各种红字提示,可以在启动中加入 -DEMOMODE

ue4editor  C:\DemoProject\DemoProject.uproject -game -DEMOMODE

 29.

ue中阴影缺失有可能是因为包围盒的原因,物体的一部分在视野内,但物体消失,也有可能是包围盒的问题,可设置缩放boundsScale,静态网格体的包围盒通常是自动根据模型生成的。骨架网格体,如果 没有设置过物理资源(注意,不是阴影物理资源),则包围盒将根据形体,自动生成,如果设置过物理资源,则包围盒将根据物理资源的所有形体进行构建,这可以加快包围盒构建速度,但也可能造成包围盒构建的大小出现问题。如果对静态网格体和骨架网格体自动生成的包围盒不满意,可以设置boundsExtension,设置的值将加到包围盒上,可以是负值。

  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值