UE C++错误与注意
通过使用中出错又解决之来逐渐学习Unreal Engin
的框架边界,同时整理出自己在UE
中的使用感悟与注意事项,使得自己使用起来得心应手而又游刃有余。
最上方是最新的哦!
画面所有图标从Z轴上扁平化,Shader编译有问题
报错参考图:
原因你根本想不到:
摄像机近处的裁剪距离设置为0
Engine > General Settings > Settings > Near Clip Plane设置平面
尽量不要使用此值太低,因为它会对 z 缓冲区精度产生不利影响。因为不仅仅影响PIE的相机,还影响游戏的相机
编译时直接报错-532462766
MSB3073 The command "E:\UE4_27Source\Engine\Build\BatchFiles\Build.bat -Target="xxxEditor Win64 Development -Project=\"E:\Unreal\xxx\xxx.uproject\"" -Target="ShaderCompileWorker Win64 Development -Quiet" -WaitMutex -FromMsBuild" exited with code -532462766.
不管是重新编译,还是删除了其他生成的中间文件,二进制文件,一样。
报错参考图[借用]:
Git
的原因,因为git
里有些冲突的内容。我就是没有去管理好git,没有及时去处理git状态。直接删除.git
能解决,但是你懂得。。。所以请管理好git
要么先别用,要用就别懒(说我自己呢)。
EnhanceInput报错
报错参考图:
编辑器运行游戏时,弹出这种错误,也没有说在哪里,只有EnhanceInput相关内容。
解决方案:
看InputMappingContext
文件是否存在None
项,原因就是这个引起的。
出现 Unable to instantiate module 'UnrealEd'问题
报错参考图:
解决方案:
是不是在Source
下的XX.Build.cs
引用模块引用了一个奇怪的模块,名字类似UnrealEd
。
或者参考其他的图片:
单独的小点看你有没有犯错
- 不要在UE4编辑蓝图过程中编译c++代码,会导致热重载bug不同步,得重启引擎。
- 不要在构造函数传递this指针使用权
输出UENUM的字符串值
如果枚举使用了UENUM
宏定义的,那么可以通过如下直接获得字符串值
// 定义枚举
UENUM(BlueprintType)
enum class ENumType : uint8
{
One,
Two,
MaxType
};
ENumType NumData = ENumType::One;
// 获取枚举指针
UEnum* EnumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("ENumType"), true);
// 传字符串
FString EnumStr = EnumPtr->GetNameByValue((int)NumData).ToString();
// 或者
FString EnumStr2 = EnumPtr->GetNameStringByValue((int)NumData);
打印当前函数名
void UTestObject::UTestFunc()
{
UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__));
}
其中__FUNCTION__
代表的主浊当前函数名。
UE4小数点只有6位
float FloatNum = 3.1415926;
FString Cast_FloatNum = FString::SanitizeFloat(FloatNum);
// 打印出来
UKismetSystemLibrary::PrintString(this,Cast_FloatNum);
◇ 生成的组件要写上名字,不能为空
CollisionComponent = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionComponent"));
上边TEXT()
内的名字为空的话,UE4编辑器直接崩溃
◇ 如果在C++中修改了默认的值,没效果
如果在修改前,已经使用C类生成了蓝图,那么蓝图对应的值的默认状态会变,但值不会改变,也就是如果当前值与c中的值不同,蓝图中对应值后面的设置默认黄箭头
会出现。
◇ CreateWidget的第一个参数
可能报错
The given OwningObject is not of a supported type for use with CreateWidget.
◇ 蓝图construst
出错
[Compiler] Cannot construct objects of type '/Script/HttpReq.HttpServerBase' in Construct Object from Class
主要出现在蓝图里进行construct
时报错,主要是你这个类没有没有蓝图化标记
,注意下图中箭头位置要添加,默认是会添加,插件好像不会,如果没有需要添加。
注意:如果没有添加时已经编译,那么添加编译完后,需要重新启动
UE4编辑器
才会看到效果。
◇ 使用游戏的主模块
每个游戏项目在C++
工程里会生成一个与项目名称对应的.h
与.cpp
文件,如果想使用游戏的主模块,可以在项目名.h
文件下添加如下。
主模块名为:F
+项目名
+Module
。
项目名不用也不能首字母大写
。
// 项目名.h
#include "CoreMinimal.h"
// 下边是新加了
class F项目名Module:public FDefaultGameModuleImpl
{
public:
// 模块加载时调用
virtual void StartupModule() override;
// 模块卸载时调用
virtual void ShutdownModule() override;
};
然后对应的.cpp
里,除了对应函数的书写,还要修改下宏IMPLEMENT_PRIMARY_GAME_MODULE
的部分。
// 项目名.cpp
#include ...// 省略
void F项目名Module::StartupModule()
{
FDefaultGameModuleImpl::StartupModule();
UE_LOG(LogTemp,Warning,TEXT("主模块初始化"));
}
void F项目名Module::ShutdownModule()
{
FDefaultGameModuleImpl::ShutdownModule();
UE_LOG(LogTemp,Warning,TEXT("主模块注销"));
}
IMPLEMENT_PRIMARY_GAME_MODULE(/*原来是:FDefaultGameModuleImpl*/FhttptestModule, httptest, "httptest");
修改第一个参数,修改成主模块名,搞定。
ConstructorHelpers::FObjectFinder
前加不加static
关键字static
使变量成为静态的。这意味着每次调用时具有相同的值。
变量的确切值是在第一次调用方法时确定的。
例如,当一个actor
的所有实例都应该有一个指向相同共享资产的指针时,这很有用。如果您将此类变量设为静态,引擎将只搜索一次资产 - 而不是每次生成角色时。
在您的代码中,每次调用您的方法时可能需要不同的资产引用,因此不需要静态。
Exhausted all retries!
编辑器崩溃后的错误弹框还没有关闭,就开始IDE
编译。就会出现这种错误。
不能将 未区分范围的枚举 重新声明为 区分范围的枚举
在.h
文件名传枚举类型的参数时,可能在前面有enum
前缀,需要删除,其他引用这个枚举来源。
编译引擎代码时出错的话,会导致部分模块有问题
找到自编译对应的模块位置
E:\xx...xx\UnrealEngine-4.27\Engine\Plugins\Online\OnlineSubsystemUtils
下
删除Binaries
文件夹,使用IDE
打开引擎项目重新编译,此时项目会自己搜索到对应的位置然后重新生成对应文件
引擎项目就是对应着自编译ue4的项目
E:\xx...xx\UnrealEngine-4.27\UE4.sln
设置了GameMode
的DefaultPawnClass
但是游戏不生成,而只生成SpectatorPawn
-
先检查简单的,看是不是在
播放(Play)
游戏时,选中的是模拟(Simulate)
,部分情况下有可能是这个原因。 -
如果使用的基于
GameModeBase
的游戏模式,不会出现这个问题。那原因可能如下:在使用基于
GameMode
的游戏模式的话,会比GameMode
多一个状态控制的流程。其中有一个属性:bDelayedStart
默认为false
如果一旦有玩家进入这个关卡,默认情况下
GameMode
的MatchState
会从WatingToStart
(等待开始)直接进入到InProgress
(游戏中)状态,直接进入游戏中玩,比如守望先锋的加入游戏机制。而有时候,如果不想让玩家玩,而是像手动控制,比如等人加入齐了,再手动开始,而这时候玩家只是个观察者,从而先生成
Speactator
,默认玩家可以自由飞行。比如CS里死亡后的控制视角。如果想达到此目的就需要将bDelayedStart=true;
,这样刚进入GameMode的话会先生成观察者,等待GameMode
进入InProgress
状态时,被切换成DefaultPawnClass
。
BoxComponent
等碰撞组件点击
、滑入
、滑出
等回调失效。
原因:UI会阻止鼠标事件,可能是因为这个原因。
- 如果在点击地方覆盖着UI组件,而且这个组件设置了
visible
。这样会阻止点击滑入滑出的鼠标操作,对碰撞组件的响应。 - 如果点击处没有UI组件的话,有可能整个
Widget
的Visibility
属性设置为visible
,这样这个UI的空白区也会阻挡鼠标事件无法穿透。
解决方法
注意UMG
的Visibility
的属性。
- 默认应该设置为
Not Hit-Testable (Self only)
,对应c++
里的ESlateVisibility::SelfHitTestInvisible
。这种模式如果有空白不阻断事件,如果是Visible
空白处会阻断事件。
设置了Replicates
,但是actor
没有复制
如果是想生成一个大家都能看到的组件。但是设置了Replicates
,只有主机能看到,客户端看不到。有可能是此actor设置了这个属性。
这个属性表示只和自己的拥有者相关,所以也只有拥有者能看到。而发生这种情况下,应该不是拥有者生成此Actor,所以也只有服务器能看到。
评论