一般在我们的地图上面会有对应场景的小地图,做法有很多种,这次分享一下使用SceneCaptureComponent2D这个组件去处理小地图。
这个的原理是使用摄像机,创建一个RenderTarget和对应材质,通过实时拍摄画面,传递到创建的UI中。
1.创建拍摄带有SceneCaptureComponent2D组件的C++类:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/SceneCapture2D.h"
#include "MiniMapActor.generated.h"
class ARoleBase;
/**
*
*/
UCLASS()
class RPGGAME_API AMiniMapActor : public ASceneCapture2D
{
GENERATED_BODY()
public:
AMiniMapActor();
virtual void BeginPlay() override;
/*更新小地图Actor位置*/
void UpdateMiniMapActorLocation();
protected:
virtual void Tick( float DeltaSeconds) override;
protected:
ARoleBase* PlayerRef;
UPROPERTY(EditAnywhere,Category = "Properties")
float CameraDistance;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "Other/MiniMapActor.h"
#include "Kismet/GameplayStatics.h"
#include "Gameplay/RoleBase.h"
#include "Components/SceneCaptureComponent2D.h"
AMiniMapActor::AMiniMapActor()
{
PrimaryActorTick.bCanEverTick = true;
GetCaptureComponent2D()->SetRelativeRotation(FRotator(-90.0f,0.0f,0.0f));
CameraDistance = 1000.0f;
}
void AMiniMapActor::BeginPlay()
{
Super::BeginPlay();
PlayerRef = Cast<ARoleBase>(UGameplayStatics::GetPlayerPawn(this,0));
}
void AMiniMapActor::UpdateMiniMapActorLocation()
{
if (!PlayerRef)
{
GEngine->AddOnScreenDebugMessage(-1,5.0f,FColor::Red,TEXT("11111111111"));
return;
}
const FVector PlayerLocation = PlayerRef->GetActorLocation();
const FVector NewLocation = FVector(PlayerLocation.X,PlayerLocation.Y,PlayerLocation.Z + CameraDistance);
SetActorLocation(NewLocation);
}
void AMiniMapActor::Tick(float DeltaSeconds)
{
Super::Tick(DeltaSeconds);
UpdateMiniMapActorLocation();
}
2.创建渲染使用的RenderTarget:
并创建出对应的材质:
注意选择使用遮罩和UI,注意圆形遮罩的中心点。
3.创建UserWidget,将RenderTarget材质赋值:
上述的代码中有将摄像机和角色绑定为相对位置,这样角色到一些地图的高处的时候就仍然会保持相对位置,不会穿模。
效果图:
上面有一个对应角色位置的小图标,我这里是用代码每帧处理的:
获取到角色引用之后,每帧设置提示小图标角度即可。
const FRotator PlayerRotation = PlayerRef->GetActorRotation();
PlayerTip->SetRenderTransformAngle(PlayerRotation.Yaw);