UE4 总结十四
Posted zhangxiaofan666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UE4 总结十四相关的知识,希望对你有一定的参考价值。
1.模块加载的顺序问题
在引入插件时,会报错,可以看出是编辑器启动时,WidgetTree没有识别到该控件
解决方法:
在插件的uplugin文件中将插件的加载顺序从Default改成PreDefault,这样先加载模块,再加载引擎,就不会报错了
1 获得鼠标在世界坐标下的位置和方向,在PlayerController中的ProjectMousePositionToWorld方法,计算猪脚和鼠标的位置差来得到方向向量,让猪脚随着鼠标移动
2
UPROPERTY(BlueprintAssignable) // 蓝图可以动态地为委托赋予事件
FOnKingDeathSignature OnKingDeath;// 多播委托实例,在Broadcast之后调用该委托上的方法
3
https://blog.csdn.net/luomogenhaoqi/article/details/88994343
4
多客户端中勾选actor的replicated movement且开启物理模拟时,可能会出现位置来回闪动的情况,建议关闭replicated movement
5 一个很怪的bug,在服务端生成技能actor,技能多播怪物动画,发现怪物走了很远时,客户端突然不播放怪物动画,调试时发现,怪物走到很远的某个点时,该客户端的技能都不打印日志了
解决办法:
在网络复制中有个Net Cull Distance Squared,当技能actor离怪物很远时,就不会进行网络同步了,要么把距离设的很大,要么把该actor绑到怪物类上,要么勾选Always Relevant,不管距离远近都更新网络同步
6
对于一个mesh而言,我们也可以拿到Mesh在动画某个时刻的垂直于mesh的右侧方向量,前向向量,上侧向量
7
如果要做两个向量的叉积,用 cross函数
8
bool foundObject = (Object == NULL);
return foundObject;
9
#define FSTRING_TO_INT(FStringValue) FCString::Atoi(*FStringValue)
#define ACreateTimer(Handle, Obj, Method, Rate, bLoop)\\
GetWorldTimerManager().SetTimer(Handle, Obj, Method, Rate * GetActorTimeDilation(), bLoop)
10
报错
找到FSlateColor类,发现缺少了SlateCore模块,在build.cs中加入该模块即可
11
在UE4源码中有很多类继承了S开头的类,主要集中在Slate模块中,负责渲染功能,而U开头的类继承了UObject偏上层,主要负责游戏逻辑业务,为了保证垃圾回收,反射专门添加的机制,如果是F开头,是纯粹的c++类,是最底层的
12
发现一个奇怪bug,在写slate时报错,然而在build.cs中加了Slate,SlateCore和UMG三个模块还是报错
报错信息
2>MyEditableText.cpp.obj : error LNK2019: unresolved external symbol "public: static class FMoveCursor __cdecl FMoveCursor::ViaScreenPointer(struct FVector2D,float,enum ECursorAction)" (?ViaScreenPointer@FMoveCursor@@SA?AV1@UFVector2D@@MW4ECursorAction@@@Z) referenced in function "public: void __cdecl UMyEditableText::ShowMouseLight(void)" (?ShowMouseLight@UMyEditableText@@QEAAXXZ)
2>C:\\UE4\\Project\\TestProject\\aaa\\Binaries\\Win64\\UE4Editor-aaa-Win64-DebugGame.dll : fatal error LNK1120: 1 unresolved externals
解决方法
FMoveCursor没有暴露出来,他前面需要加一个SLATE_API才能被其他Module使用。
不过值得注意的是SLATE_API只有在Slate模块中才能使用,不能把该宏标记放到自己的模块中使用,会报编译错误
还有一次也是报链接错误,不过这次加上"UnrealEd"模块编译就过了
13
在调用ProcessEvent第二个参数传入函数指针对应函数的参数,如果该函数有多个参数,封装到一个自定义的struct中,带一个return,用这个返回值来判断是否调用该函数成功的标识
这种方法很怪,为什么不直接调该函数,而是先拿到函数指针,再通过函数指针调函数?
原因:比如某个类继承了actor是在蓝图创建的,并且该函数写在了蓝图里,c++获取不到,那么可以用这种方式在c++拿到该蓝图类的某个函数
bool UCWMaker::IsMatchSituation(const FString& InFuncName)
// Check Func is valid
UFunction* Function = FindFunction(FName(*InFuncName));
if (nullptr == Function)
CWG_ERROR(">> %s::IsMatchSituation, Function[%s] is nullptr!!!", *CWG_NAME(this), *InFuncName);
return false;
// define a container
struct FDynamicArgs
bool Return = false;
;
// create the container
FDynamicArgs Args = FDynamicArgs();
ProcessEvent(Function, &Args);
return Args.Return;
14 vs2017代码自动补齐
在Tools->Options
15 寻找到指定文件夹下的所有文件的代码
// 遍历文件夹下指定类型文件
// OutFiles 保存遍例到的所有文件
// FilePath 文件夹路径 如 "D:\\\\MyCodes\\\\LearnUE4Cpp\\\\Source\\\\LearnUE4Cpp\\\\"
// Extension 扩展名(文件类型) 如 "*.cpp"
void Test::ScanDirectory(TMap<FString, FString>& OutFiles, const FString& InFilePath, const FString& InExtension)
//IFileManager::Get().FindFilesRecursive(FindedFiles, *InFilePath, TEXT("*.uasset"), true, false);
FindFilesRecursive(OutFiles, *InFilePath, *InExtension, true, false);
void Test::FindFilesRecursive(TMap<FString, FString>& FileNames, const TCHAR* StartDirectory, const TCHAR* Filename, bool Files, bool Directories, bool bClearFileNames /*= true*/)
if (bClearFileNames)
FileNames.Reset();
FindFilesRecursiveInternal(FileNames, StartDirectory, Filename, Files, Directories);
void Test::FindFilesRecursiveInternal(TMap<FString, FString>& FileNames, const TCHAR* StartDirectory, const TCHAR* Filename, bool Files, bool Directories)
FString CurrentSearch = FString(StartDirectory) / Filename;
TArray<FString> Result;
IFileManager::Get().FindFiles(Result, *CurrentSearch, Files, Directories);
for (int32 i = 0; i < Result.Num(); i++)
const FString& RFileName = Result[i];
const FString& RFullPath = FString(StartDirectory) / RFileName;
FileNames.Add(RFileName, RFullPath);
TArray<FString> SubDirs;
FString RecursiveDirSearch = FString(StartDirectory) / TEXT("*");
IFileManager::Get().FindFiles(SubDirs, *RecursiveDirSearch, false, true);
for (int32 SubDirIdx = 0; SubDirIdx < SubDirs.Num(); SubDirIdx++)
FString SubDir = FString(StartDirectory) / SubDirs[SubDirIdx];
FindFilesRecursiveInternal(FileNames, *SubDir, Filename, Files, Directories);
16
像这种遍历数组,删除其实很容易出错的,我们说遍历时候remove某个元素要非常注意,这种用法是错误的
17
ue4 vs的配置和番茄插件的基本配置教程
https://www.bilibili.com/video/av61492085/
18
UE4材质_运用数学计算制作深洞效果
https://www.bilibili.com/video/av61206165
19
UE4超大地图的无缝加载和卸载
https://www.bilibili.com/video/av61987764
20
Open world optimization(LOD层面的优化)
https://www.bilibili.com/video/av59682722
https://www.youtube.com/watch?v=e0lK4DNtA9E
21
如果场景中有大量的树,如何选取所有同样的树?右键其中一棵树->选择->选择所有具有同样材质的项
22
Tweakptr和TSoftPtr的区别,为什么要引入这两个概念?
Tweakptr是引擎对于智能指针的一个弱引用的实现,就是不记录智能指针的引用计数,这样真正的指针不会因为这个 Tweakptr的指向而不能被释放。对应的是智能指针是TSharedPtr。
另外引擎还有一个TWeakObjectPtr,是表示不真正引用UObject,而导致这个UObject不能被GC,因为GC是通过查找引用关系来决定是否要GC。
TSoftPtr的作用不实际引用一个资源,而是记录这个资源的路径,这样这个类型不会一开始就把资源加载到内存里,而是可以让用户手动决定加载时机。
23
24.
1 这个节点是该物件从创建后开始计算,经历的时间
25.加载关卡时不填绝对路径的关卡名是很不好的,这样会遍历所有的地图资源,很影响性能
以上是关于UE4 总结十四的主要内容,如果未能解决你的问题,请参考以下文章