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++也能写只是,要多加一些库。

核心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值