当前位置: 首页 > article >正文

UE5.3 C++ Ceiusm中的POI 制作3DUI 结合坐标转化

一.核心思路WidgetComponent + CesiumGloberAnchor

二.先制作POI

创建C++ Actor来制作,APOI。直接上代码

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CesiumGlobeAnchorComponent.h"
#include "POI.generated.h"

UCLASS()
class HMS3DUI_API APOI : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	APOI();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
	UFUNCTION(BlueprintCallable)
	void MoveToLLA(double Longtitude,double Latitude,double Altidude);
	UFUNCTION(BlueprintCallable)
	FVector GetLLA();
	// WidgetComponent
	UPROPERTY(BlueprintReadWrite,EditAnywhere, Category = WidgetComponent)
	class UWidgetComponent* WidgetComponent;
private:
	UPROPERTY(BlueprintReadOnly, EditAnywhere, meta = (AllowPrivateAccess = "true"))
	UCesiumGlobeAnchorComponent* globeAnchor;//地球组件
};

然后在CPP里,实现组件。并设置为3DUI,这里用的屏幕尺寸的。

// Sets default values
APOI::APOI()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
	WidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("WidgetComponent"));
	WidgetComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
	// 设置控件蓝图
	//UClass* Widget = LoadClass<UUserWidget>(NULL, TEXT("/Script/UMGEditor.WidgetBlueprint'/HMS3DUI/POI.POI_C'"));
	static ConstructorHelpers::FClassFinder<UUserWidget>WidgetClass(TEXT("/Script/UMGEditor.WidgetBlueprint'/HMS3DUI/POI.POI_C'"));
	WidgetComponent->SetWidgetClass(WidgetClass.Class);
	//设置渲染方式,是渲染到屏幕还是世界中
	WidgetComponent->SetWidgetSpace(EWidgetSpace::Screen);
	//设置绘制大小
	WidgetComponent->SetDrawSize(FVector2D(1280, 720));
	globeAnchor = CreateDefaultSubobject<UCesiumGlobeAnchorComponent>(TEXT("CesiumGlobe"));
}

两个函数,无论时显示UI现在的地方,还是UI输入去其它地方都能实现,坐标的转换。

void APOI::MoveToLLA(double Longtitude, double Latitude, double Altidude)
{
	globeAnchor->MoveToLongitudeLatitudeHeight(FVector(Longtitude, Latitude, Altidude));
}

FVector APOI::GetLLA()
{
	FVector tmp = globeAnchor->GetLongitudeLatitudeHeight();
	if (globeAnchor)
	{
		return tmp;
	}
	return FVector(0,0,0);
}

简单做个UI,这个UI把锚点放到屏幕中心。就能实现3DUI刚好在那个点上。

通过UIManager, Spawn和管理3DUI.

void AHMSUIManager::Spawn3DUI(double Longtitude, double Latitude, double Altidude)
{
	/*UClass* MyTmpClass = LoadClass<AActor>(this, TEXT("/Script/Engine.Blueprint'/HMS3DUI/BP_POI.BP_POI_C'"));
	if (MyTmpClass)
	{
		AActor* SpawnActor = GetWorld()->SpawnActor<AActor>(MyTmpClass, FVector::ZeroVector, FRotator::ZeroRotator);
	}*/
	UClass* MyTmpClass = LoadClass<APOI>(this, TEXT("/Script/Engine.Blueprint'/HMS3DUI/BP_POI.BP_POI_C'"));
	APOI* poi = GetWorld()->SpawnActor<APOI>(MyTmpClass);
	poi->MoveToLLA(Longtitude, Latitude, Altidude);
}

简单的通过UI,传值调用。

这里当时卡住了,我继承了C++类来进一步写POI的写如UI的TEXT。获得WidgetComponet并GetWidget 转换为 POI这个Widget。这样就可以实现Actor拿到它想显示的UI,并赋值修改这个UI。

而且涉及经纬度,ToText需要设置小数点后的位数 7。

自动在对应经纬产出物体,显示经纬高

三. 延申功能,在鼠标射线中,点击的地方生成3DUI。

之所以用蓝图,因为快。C++也能写只是,要多加一些库。

核心


http://www.kler.cn/a/452427.html

相关文章:

  • 【day17】多线程基础
  • 【Java基础面试题046】Java中的注解原理是什么?
  • flink sink doris
  • 外包干了两年,技术退步明显...
  • LeetCode每日三題(三
  • shell学习简介(一)
  • 【三维重建】去除瞬态物体Distractor汇总
  • 【行空板K10】评测资料准备
  • 华为OD机试 密码截获(C/JAVA)
  • NNDL 作业11 LSTM
  • FFmpeg在python里推流被处理过的视频流
  • MyBatis如何处理延迟加载?
  • 三维扫描在汽车/航空行业应用
  • Java web的发展历史
  • C#中的委托机制:深入理解与应用
  • 基于earthSDK三维地图组件开发
  • vue.js 指令的修饰符
  • 16.2、网络安全风险评估技术与攻击
  • 解决Gradle下载很慢,运行及打包很慢
  • 在开发嵌入式系统时,尤其是处理大数时,会遇到取值范围的问题。51单片机通常没有内建大整数支持,因此我们需要采用不同的方法来解决这一问题