Unity的Gizmos可以很方便的在编辑器下进行调试,Unreal中也有一些办法可以达到效果。

本文主要参考:https://zhuanlan.zhihu.com/p/363625037,进行了一些简化。并在Unreal 4.27中实现。

具体流程如下:

  1. 需要绘制Gizmo的Actor挂载继承UPrimitiveComponent的组件;该组件重写了CreateSceneProxy方法,这个方法里可以拿到PDI绘制
  2. 然后进行这个组件的编写(继承UPrimitiveComponent实际上也继承了USceneComponent),手动挂载到Actor上就可以绘制Gizmo了
  3. 再在Actor的构造函数中编写自动挂载该组件的逻辑,方便使用

先来编写绘制Gizmo的组件,这里命名为UMyPrimitiveComponent:

MyPrimitiveComponent.h (MYPROJECT_API注意替换)

//MyPrimitiveComponent.h

#pragma once

#include "CoreMinimal.h"
#include "Components/PrimitiveComponent.h"
#include "PrimitiveSceneProxy.h"
#include "MyPrimitiveComponent.generated.h" UCLASS(ClassGroup = (Custom), meta = (BlueprintSpawnableComponent))
class MYPROJECT_API UMyPrimitiveComponent : public UPrimitiveComponent
{
GENERATED_BODY() public:
//绘制逻辑主要在这里
virtual FPrimitiveSceneProxy* CreateSceneProxy() override; //如果要在非选中情况下始终绘制的话,需要有Bounds信息,所以要重写该函数
virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const;
};

MyPrimitiveComponent.cpp

//MyPrimitiveComponent.cpp
#include "MyPrimitiveComponent.h" FPrimitiveSceneProxy* UMyPrimitiveComponent::CreateSceneProxy()
{
class FMySceneProxy : public FPrimitiveSceneProxy
{
public: SIZE_T GetTypeHash() const override
{
static size_t UniquePointer;
return reinterpret_cast<size_t>(&UniquePointer);
} FMySceneProxy(const UPrimitiveComponent* InComponent) : FPrimitiveSceneProxy(InComponent)
{
CacheInComponent = InComponent;
bWillEverBeLit = false;
} virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_Draw3DAgentSceneProxy_GetDynamicMeshElements); for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
if (VisibilityMap & (1 << ViewIndex))
{
const FSceneView* View = Views[ViewIndex];
FPrimitiveDrawInterface* PDI = Collector.GetPDI(ViewIndex); //拿到Actor的矩阵绘制,而不是Component自己的
const FMatrix& LocalToWorld = CacheInComponent->GetTypedOuter<AActor>()->GetTransform().ToMatrixWithScale(); //绘制函数可以去看下PrimitiveDrawingUtils.cpp
DrawOrientedWireBox(PDI
, LocalToWorld.TransformPosition(FVector::ZeroVector)
, LocalToWorld.GetScaledAxis(EAxis::X)
, LocalToWorld.GetScaledAxis(EAxis::Y)
, LocalToWorld.GetScaledAxis(EAxis::Z)
, FVector(100.0, 100.0, 100.0)
, FLinearColor(1.0, 0.0, 0.0, 1.0)
, SDPG_World
, 1.0);
}
}
}
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
{
/*const bool bVisibleForSelection = IsSelected();
const bool bShowForCollision = View->Family->EngineShowFlags.Collision && IsCollisionEnabled(); FPrimitiveViewRelevance Result;
Result.bDrawRelevance = (IsShown(View) && bVisibleForSelection) || bShowForCollision;
Result.bDynamicRelevance = true;
Result.bShadowRelevance = IsShadowCast(View);
Result.bEditorPrimitiveRelevance = true;
Result.bEditorNoDepthTestPrimitiveRelevance = true; */
//上面这段表示选中绘制Gizmo FPrimitiveViewRelevance Result;
Result.bDrawRelevance = true;
Result.bDynamicRelevance = true;
Result.bShadowRelevance =false;
Result.bEditorPrimitiveRelevance = true;
Result.bEditorNoDepthTestPrimitiveRelevance = true;
//这段表示始终绘制 return Result;
} virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); }
uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); } private:
const UPrimitiveComponent* CacheInComponent;
}; return new FMySceneProxy(this);
} FBoxSphereBounds UMyPrimitiveComponent::CalcBounds(const FTransform& LocalToWorld) const
{
return FBoxSphereBounds(FBox(FVector(-50, -50, -50), FVector(50, 50, 50))).TransformBy(LocalToWorld);
//因为缩放是1,这里填的就是实际尺寸,也可以遍历所有组件取最大Bounds.
}

然后手动再挂载一下组件,就有效果了:

如果需要像Unity那样;直接就有Gizmo,可以在Actor构造函数中编写逻辑自动挂载组件:

AMyTestActor::AMyTestActor()
{
UBBoxActorGizmoComponent* Gizmo = CreateDefaultSubobject<UBBoxActorGizmoComponent>(TEXT("Gizmo"));
if (Gizmo)
{
Gizmo->SetupAttachment(GetRootComponent());
}
}

UE4 绘制Gizmo的更多相关文章

  1. Unity3D脚本中文系列教程(十七)

    http://dong2008hong.blog.163.com/blog/static/469688272014032332976/ ◆ Static function PrefixLabel(to ...

  2. 从Unity中的Attribute到AOP(八)

    本文将讲一下在UnityEditor命名空间下的一些特性. CallBackOrder,这个Attribute是所有带callback index的Attribute的基类,由于官方也没有给出详细的说 ...

  3. Unreal学习笔记2-绘制简单三角形

    目录 1. 概述 2. 详论 2.1. 代码实现 2.2. 解析:Component 2.3. 解析:材质 2.4. 解析:包围盒 2.5. 解析:Section 3. 其他 4. 参考 1. 概述 ...

  4. UE4 Tutorial - Custom Mesh Component 用于绘制自定义网格的插件CustomMeshComponent

    UE4 中用于绘制自定义网格的插件CustomMeshComponent. 转载: UE4 Tutorial - Custom Mesh Component   Over the last few w ...

  5. unity gizmo绘制圆形帮助调试

    using UnityEngine; using System.Collections; using System; public class LearnGrazio : MonoBehaviour ...

  6. UE4射线的碰撞与绘制

    http://blog.csdn.net/qq992817263/article/details/51800657 //起点 终点 FHitResult RayGetHitResult(FVector ...

  7. [UE4][Canvas]用C++代码绘制血条(HealthBar)

    转自:http://aigo.iteye.com/blog/2275110 参考自Epic官方项目StrategyGame 血条效果: StrategyHUD.h StrategyHUD.cpp

  8. 【UE4 C++】绘制函数 Debug drawing functions

    基于UKismetSystemLibrary /** Draw a debug line */ UFUNCTION(BlueprintCallable, Category="Renderin ...

  9. UE4命令行使用,解释

    命令行在外部 从命令行运行编辑项目 1 导航到您的[LauncherInstall][VersionNumber]\Engine\Binaries\Win64 目录中. 2 右键单击上 UE4Edit ...

  10. UE4 在C++ 动态生成几何、BSP体、Brush ---- Mesh_Generation

    截至UE4  4.10 runtime 无法生成BSP类 ,只能通过自定义的Mesh的Vertex 进行绘制 ( Google 考证,能改UE4源码的请忽略 ) 可用到的 UE4 集成的Render ...

随机推荐

  1. 记一次 .NET某管理局检测系统 内存暴涨分析

    一:背景 1. 讲故事 前些天有位朋友微信找到我,说他们的WPF程序有内存泄漏的情况,让我帮忙看下怎么回事?并且dump也抓到了,网上关于程序内存泄漏,内存暴涨的文章不计其数,看样子这个dump不是很 ...

  2. 【FAQ】HarmonyOS SDK 闭源开放能力 —Push Kit

    1.问题描述 升级到4.0.0.59版本后,通过pushService.getToken获取华为的token时报如下错误:Illegal application identity. 解决方案 Mate ...

  3. HarmonyOS应用开发—资源分类与访问

     应用开发过程中,经常需要用到颜色.字体.间距.图片等资源,在不同的设备或配置中,这些资源的值可能不同. ● 应用资源:借助资源文件能力,开发者在应用中自定义资源,自行管理这些资源在不同的设备或配置中 ...

  4. Excel 特殊分组汇总示例

    期望结果: 按照成绩划分区间段来分组时,定义好值的划分区间后,只需用 pseg 函数便可以将分数分好段,然后统计出各段人次即可. SPL 代码如下:   A B 1 =clipboard().impo ...

  5. 填报表中也可以添加 html 事件

    在实际的项目开发中,填报表的应用十分广泛. 多数情况下,填报表会作为整个项目的一部分配合需求灵活使用,但有时也会受大项目环境的影响,产生一些特别的要求.比如,通常报表单元格的数据类型大多是文本,有时却 ...

  6. nginx重新整理——————分析log数据[六]

    前言 简单介绍一下goaccess. 正文 安装: yum install epel-release yum install GeoIP GeoIP-devel GeoIP-data yum inst ...

  7. redis 简单整理——bitmaps[十二]

    前言 简单介绍一下bitmaps这个东西. 正文 我们都知道bitmaps 翻译过来就是二进制. 那么二进制可以存一些什么呢? 图片.视频,还可也存些什么呢? 现代计算机用二进制(位)作为信息的基础单 ...

  8. C++ 访问说明符详解:封装数据,控制访问,提升安全性

    C++ 访问说明符 访问说明符是 C++ 中控制类成员(属性和方法)可访问性的关键字.它们用于封装类数据并保护其免受意外修改或滥用. 三种访问说明符: public:允许从类外部的任何地方访问成员. ...

  9. 云原生微服务的下一站,微服务引擎 MSE 重磅升级

    ​简介:管好微服务,成为云原生时代的新难题. 管好微服务,成为云原生时代的新难题. 从建好微服务到管好微服务,差的虽是一个字,连接起两边的却需要大量的微服务落地经验.因为软件架构的核心挑战是解决业务快 ...

  10. TSDB时序数据库时序数据压缩解压技术浅析

    ​简介: 目前,物联网.工业互联网.车联网等智能互联技术在各个行业场景下快速普及应用,导致联网传感器.智能设备数量急剧增加,随之而来的海量时序监控数据存储.处理问题,也为时序数据库高效压缩.存储数据能 ...