[程式] 在UE4 Editor绘制除错用的元件

楼主: yekdniw (yekdniw)   2020-06-25 00:00:06
网页版
https://yekdniwue.blogspot.com/2020/06/ue4-editor.html
简介
在游戏中,我们都知道可以使用Blueprint的DrawDebug系列的功能,
用来绘制圆球,胶囊体等物件提供除错。
但是如果想在编辑器的View视窗用DrawDebug是做不到的(注1),
至少UE4引擎内部并不是这样用。
注1.我有试过在ConstructorScript呼叫DrawDebugSphere,结果是会画出来,
但是永远不会消失了。
不过引擎是有提供编辑器除错用的显示功能的,我们可以在几个地方看到:
1. Visual Logger
2. EQS Testing Pawn
3. NavigationTestingActor
使用Visual Logger可以在编辑器看到AI角色的位置资讯被记录下来,
也可以自己透过API纪录想要的资讯,如图所示。
[图1.]
EQS Testing Pawn则是可以随着编辑过程的状况不同,显示/更新Query的结果,
如图所示。
[图2.]
NavigationTestingActor是比较罕见的功能,可以在编辑器就预览路径搜寻的结果。
有个时候专案也会需要这方面的功能,如果没有心理准备,
就直接看上面三个系统的实作,通常会被复杂的程式码劝退。
这次我硬著头皮研究并试着实作了一轮,简单的做个笔记与分享。
最主要是去除复杂的程式码,只列出最基本要实作的项目。有需要改进的部分再从上面提
到的系统抽取出来即可。
本篇文章的内容以NavigationTestingActor为出发点作分析,虽然比较少见,但似乎是这
几个系统里面相对简单的部份。
架构组成
1. AActor
2. URenderComponent
3. FSceneProxy
要完成这个功能,首先要有三个class,一个就是显示项目要依附在的Actor。
然后要为这个Actor新增自定义的RenderComponent,作为显示用。
在RenderComponent内会创出自定义的SceneProxy,
你要绘制的项目要实作在SceneProxy的函式内。
以下实际用TestActor, TestRenderComponent, TestSceneProxy分别做为案例。
TestActor要实作的项目
在TestActor的member加上
UPROPERTY()
class UTestRenderComponent* TestRenderComp;
如果只想让这个功能在Editor中出现,可以使用macro
#if WITH_EDITORONLY_DATA
#endif
将所有使用到TestRenderComponent的地方夹起来。
TestActor的Constructor加上
TestRenderComp =
CreateDefaultSubobject<UTestRenderComponent>(TEXT("TestRenderComp"));
TestRenderComp->PostPhysicsComponentTick.bCanEverTick = false;
根据需求,Override PreEditChange或PostEditChangeProperty或PostEditMove。
在有资料变动的时候呼叫MarkRenderStateDirty。
TestRenderComp->MarkRenderStateDirty();
PostEditChangeProperty内可以实作property内容变动后该做的事;
PostEditMove则是Actor在编辑器内被拖拉移动的时会进入的事件;
TestRenderComponent要实作的项目
首先TestRenderComponent要继承UPrimitiveComponent,然后实作下面两个函式。
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
virtual FBoxSphereBounds CalcBounds(const FTransform &LocalToWorld)
const override;
CreateSceneProxy就是new出SceneProxy,并且把component自己传入SceneProxy的
constructor,说这么多其实直接看程式码比较快。
FPrimitiveSceneProxy* UTestRenderComponent::CreateSceneProxy()
{
FTestSceneProxy* newSceneProxy = new FTestSceneProxy(this);
return newSceneProxy;
}
CalcBounds比较简单,就是决定这个component的bounding box范围,用来决定这个
component会不会进rendering。
可以从GetOwner拿到TestActor,然后直接回传Actor的BoundingBox即可。
FBoxSphereBounds UTestRenderComponent::CalcBounds(
const FTransform &LocalToWorld) const
{
FBox BoundingBox(ForceInit);
AActor* TestActor = GetOwner();
if (TestActor)
{
BoundingBox = TestActor->GetComponentsBoundingBox(true);
}
return FBoxSphereBounds(BoundingBox);
}
TestSceneProxy要实作的项目
TestSceneProxy反而是最复杂的项目,要实作的函式比较多,实际上要绘制的程式码也写
在这。
GetTypeHash()
Constructor(const UTestRenderingComponent* inComponent);
Destructor
GetDynamicMeshElements()
GetViewRelevance()
GetAllocatedSize()
其中GetTypeHash,Constructor, Destructor,
GetViewRelevance, GetAllocatedSize建议直接参考
Engine/Source/Runtime/NavigationSystem/Private/NavMesh/
内的NavTestRenderingComponent.cpp就好,
GetTypeHash, Destructor, GetViewRelevance我是直接照抄。
Constructor目的是要透过TestRenderingComponent拿到TestActor的资料,
存入自定义的资料结构。
在GetDynamicMeshElements会使用这些资料结构做绘制。
GetAllocatedSize要回传TestSceneProxy额外使用到的内存大小,
请参考NavTestRenderingComponent。
GetDynamicMeshElements是主要绘制的程式码入口,请参考以下的范例程式码:
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
if (!(VisibilityMap & (1 << ViewIndex)))
{
continue;
}
// Write your codes here!!
}
在Engine/Source/Runtime/Engine/Public/SceneManagement.h内
提供了许多绘制形状的函式,
所以从Constructor拿到的资料在这里传入绘图函式就可以了。
绘制的函式基本上又可以分为两大类,一类是以Get为开头的函式;
另一类则是Draw开头的函式。
Get系列要传入Material,所以需要产生FMaterialRenderProxy后传入。
Draw系列需要FPrimitiveDrawInterface (引擎缩写PDI),
可以呼叫Collector.GetPDI(ViewIndex)取得。
以上两个系列的程式码在FNavTestSceneProxy::GetDynamicMeshElements内挖的到,
请直接参考就好。
下图 为分别使用DrawWireSphereAutoSides与GetSphereMesh的范例结果。
[图3.]
[图4.]
结论
这次的范例是精简过后的程式码结果,如果想要往后钻研的话,参考
GameplayDebuggerCategory里面的使用方法是最好的。
在实作这些功能之前,最好是先在游戏中输入'开启debug模式预览结果。
在融会贯通之后,就可以针对专案开发出独特的工具。
例如在Unreal Fest Europe 2019的演讲中提到,
该Studio会在编辑器内显示被选择的Actor,
以连线的方式显示参照的对象与被参照的对象。如图 所示。
用来轻易地理解场景物件彼此的相关性, 如果场景物件关系复杂的话,这个功能会特别
有用。
[图5.]
参考资料
https://docs.unrealengine.com/en-US/Gameplay/Tools/VisualLogger/index.html
Visual Logger
https://docs.unrealengine.com/en-US/Engine/AI/EnvironmentQuerySystem/EQSPawn/index.html
EQS Testing Pawn
https://www.unrealengine.com/zh-CN/events/unreal-fest-europe-2019/blueprints-blending-system-architecture-and-creativity
Blueprints: Blending System Architecture and Creativity
Deep Silver Dambuster Studios
作者: coolrobin (泳圈)   2020-06-25 00:03:00
推推推
作者: metallican (钢铁人)   2020-06-25 01:13:00
推 太神啦 最近正在学习 感谢分享
作者: damody (天亮damody)   2020-06-25 03:20:00
good
作者: PathosCross (木偶君)   2020-06-25 15:50:00

Links booklink

Contact Us: admin [ a t ] ucptt.com