161 lines
4.5 KiB
C++
161 lines
4.5 KiB
C++
// Fill out your copyright notice in the Description page of Project Settings.
|
|
|
|
|
|
#include "MyTableIconActors.h"
|
|
#include "KismetProceduralMeshLibrary.h"
|
|
#include "TableIconActor.h"
|
|
|
|
#include "Kismet/GameplayStatics.h"
|
|
#include "Camera/CameraActor.h"
|
|
|
|
ATableIconLineActor::ATableIconLineActor()
|
|
{
|
|
PrimaryActorTick.bCanEverTick = false; // purely driven by SetPoints
|
|
|
|
USceneComponent* Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
|
|
SetRootComponent(Root);
|
|
|
|
MeshComponent = CreateDefaultSubobject<UProceduralMeshComponent>(TEXT("LineMesh"));
|
|
MeshComponent->SetupAttachment(RootComponent);
|
|
MeshComponent->SetCastShadow(false);
|
|
MeshComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
|
}
|
|
|
|
void ATableIconLineActor::SetPoints(const TArray<FVector>& NewPoints)
|
|
{
|
|
const FTransform& ActorTransform = GetActorTransform();
|
|
|
|
Points.Reset(NewPoints.Num());
|
|
|
|
Points = NewPoints;
|
|
|
|
MeshComponent->ClearMeshSection(0);
|
|
|
|
BuildLineMesh();
|
|
|
|
if (LineMaterial) MeshComponent->SetMaterial(0, LineMaterial);
|
|
}
|
|
|
|
|
|
|
|
void ATableIconLineActor::BuildLineMesh()
|
|
{
|
|
TArray<FVector> Vertices;
|
|
TArray<int32> Triangles;
|
|
TArray<FVector> Normals;
|
|
TArray<FVector2D> UVs;
|
|
TArray<FColor> Colors;
|
|
TArray<FProcMeshTangent> Tangents;
|
|
|
|
FVector Direction = FVector::ZeroVector;
|
|
const float HalfLineThickness = LineThickness * 0.5f;
|
|
|
|
for (int32 i = 0; i < Points.Num() - 1; i++) {
|
|
const FVector& PointA = Points[i];
|
|
const FVector& PointB = Points[i + 1];
|
|
|
|
Direction = (PointB - PointA).GetSafeNormal();
|
|
|
|
const FVector Right = FVector::CrossProduct(FVector::UpVector, Direction).GetSafeNormal();
|
|
|
|
const FVector Offset = Right * (LineThickness * 0.5f);
|
|
|
|
int32 Base = Vertices.Num();
|
|
|
|
Vertices.Add(PointA - Offset);
|
|
Vertices.Add(PointA + Offset);
|
|
Vertices.Add(PointB + Offset);
|
|
Vertices.Add(PointB - Offset);
|
|
|
|
Triangles.Add(Base + 0);
|
|
Triangles.Add(Base + 1);
|
|
Triangles.Add(Base + 2);
|
|
|
|
Triangles.Add(Base + 0);
|
|
Triangles.Add(Base + 2);
|
|
Triangles.Add(Base + 3);
|
|
}
|
|
|
|
|
|
for (int i = 0; i < Vertices.Num(); i++)
|
|
{
|
|
Normals.Add(FVector::UpVector);
|
|
}
|
|
|
|
for (int i = 0; i < Vertices.Num(); i++)
|
|
{
|
|
UVs.Add(FVector2D::ZeroVector);
|
|
}
|
|
|
|
for (int i = 0; i < Vertices.Num(); i++)
|
|
{
|
|
Colors.Add(FColor::Red);
|
|
}
|
|
|
|
for (int i = 0; i < Vertices.Num(); i++)
|
|
{
|
|
Tangents.Add(FProcMeshTangent(Direction, false));
|
|
}
|
|
|
|
MeshComponent->CreateMeshSection(0, Vertices, Triangles, Normals, UVs, Colors, Tangents, false);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ATableIconWidgetActor::ATableIconWidgetActor()
|
|
{
|
|
USceneComponent* Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
|
|
SetRootComponent(Root);
|
|
|
|
PrimaryActorTick.bCanEverTick = true;
|
|
|
|
WidgetComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("WidgetComponent"));
|
|
WidgetComponent->SetupAttachment(RootComponent);
|
|
WidgetComponent->SetDrawAtDesiredSize(true);
|
|
WidgetComponent->SetWidgetSpace(EWidgetSpace::World);
|
|
WidgetComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
|
|
|
|
WidgetInteraction = CreateDefaultSubobject<UWidgetInteractionComponent>(TEXT("WidgetInteraction"));
|
|
WidgetInteraction->SetupAttachment(RootComponent);
|
|
WidgetInteraction->InteractionSource = EWidgetInteractionSource::Custom;
|
|
WidgetInteraction->InteractionDistance = 10.f;
|
|
}
|
|
|
|
void ATableIconWidgetActor::Tick(float DeltaTime)
|
|
{
|
|
Super::Tick(DeltaTime);
|
|
|
|
APlayerCameraManager* CamManager = UGameplayStatics::GetPlayerCameraManager(this, 0);
|
|
if (!CamManager) return;
|
|
|
|
FVector CamLocation = CamManager->GetCameraLocation();
|
|
FVector ToCamera = (CamLocation - GetActorLocation()).GetSafeNormal();
|
|
|
|
// Only rotate on yaw � keeps widget flat relative to table
|
|
ToCamera.Z = 0.f;
|
|
if (!ToCamera.IsNearlyZero())
|
|
SetActorRotation(ToCamera.ToOrientationRotator());
|
|
}
|
|
|
|
void ATableIconWidgetActor::SetWidgetClass(TSubclassOf<UUserWidget> InWidgetClass)
|
|
{
|
|
if (!InWidgetClass) return;
|
|
WidgetComponent->SetWidgetClass(InWidgetClass);
|
|
WidgetComponent->InitWidget();
|
|
}
|
|
|
|
UUserWidget* ATableIconWidgetActor::GetWidget() const
|
|
{
|
|
return WidgetComponent->GetUserWidgetObject();
|
|
}
|
|
|
|
|
|
|
|
void ATableIconLabelActor::SetDistance(float RealWorldUnits, const FString& UnitSuffix)
|
|
{
|
|
int32 Snapped = FMath::RoundToInt(RealWorldUnits);
|
|
SetLabelText(FString::Printf(TEXT("%d%s"), Snapped, *UnitSuffix));
|
|
} |