Files
Faye/Plugins/StevesUEHelpers/Source/StevesUEHelpers/Public/StevesEditorVisComponent.h
2026-07-03 19:56:31 +02:00

349 lines
11 KiB
C++

// Copyright Steve Streeting 2020 onwards
// Released under the MIT license
#pragma once
#include "CoreMinimal.h"
#include "Components/PrimitiveComponent.h"
#include "StevesEditorVisComponent.generated.h"
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisLine
{
GENERATED_BODY()
/// Start location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisLine")
FVector Start;
/// End location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisLine")
FVector End;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisLine")
FColor Colour;
FStevesEditorVisLine(const FVector& InStart, const FVector& InEnd,
const FColor& InColour)
: Start(InStart),
End(InEnd),
Colour(InColour)
{
}
FStevesEditorVisLine():
Start(FVector::ZeroVector),
End(FVector(100, 0, 0)),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisCircle
{
GENERATED_BODY()
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCircle")
FVector Location;
/// Rotation relative to component; circles will be rendered in the X/Y plane
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCircle")
FRotator Rotation;
/// Circle radius
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCircle")
float Radius;
/// The number of line segments to render the circle with
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCircle")
int NumSegments;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCircle")
FColor Colour;
FStevesEditorVisCircle(const FVector& InLocation, const FRotator& InRotation, float InRadius, int InNumSegments,
const FColor& InColour)
: Location(InLocation),
Rotation(InRotation),
Radius(InRadius),
NumSegments(InNumSegments),
Colour(InColour)
{
}
FStevesEditorVisCircle():
Location(FVector::ZeroVector),
Rotation(FRotator::ZeroRotator),
Radius(50), NumSegments(12),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisArc
{
GENERATED_BODY()
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
FVector Location;
/// Rotation relative to component; arcs will be rendered in the X/Y plane
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
FRotator Rotation;
/// Minimum angle to render arc from
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
float MinAngle;
/// Maximum angle to render arc to
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
float MaxAngle;
/// Circle radius
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
float Radius;
/// The number of line segments to render the circle with
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
int NumSegments;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisArc")
FColor Colour;
FStevesEditorVisArc(const FVector& InLocation, const FRotator& InRotation, float InMinAngle, float InMaxAngle,
float InRadius, int InNumSegments,
const FColor& InColour)
: Location(InLocation),
Rotation(InRotation),
MinAngle(InMinAngle),
MaxAngle(InMaxAngle),
Radius(InRadius),
NumSegments(InNumSegments),
Colour(InColour)
{
}
FStevesEditorVisArc():
Location(FVector::ZeroVector),
Rotation(FRotator::ZeroRotator),
MinAngle(0),
MaxAngle(180),
Radius(50), NumSegments(12),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisSphere
{
GENERATED_BODY()
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisSphere")
FVector Location;
/// Sphere radius
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisSphere")
float Radius;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisSphere")
FColor Colour;
FStevesEditorVisSphere(const FVector& InLocation, float InRadius, const FColor& InColour) :
Location(InLocation),
Radius(InRadius),
Colour(InColour)
{
}
FStevesEditorVisSphere():
Location(FVector::ZeroVector),
Radius(50),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisBox
{
GENERATED_BODY()
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisBox")
FVector Location;
/// Size of box in each axis
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisBox")
FVector Size;
/// Rotation relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisBox")
FRotator Rotation;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisBox")
FColor Colour;
FStevesEditorVisBox(const FVector& InLocation, const FVector& InSize, const FRotator& InRot,
const FColor& InColour) :
Location(InLocation),
Size(InSize),
Rotation(InRot),
Colour(InColour)
{
}
FStevesEditorVisBox():
Location(FVector::ZeroVector),
Size(FVector(50, 50, 50)),
Rotation(FRotator::ZeroRotator),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisCylinder
{
GENERATED_BODY()
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCylinder")
FVector Location;
/// Height of cylinder
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCylinder")
float Height;
/// Radius of cylinder
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCylinder")
float Radius;
/// Rotation relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCylinder")
FRotator Rotation;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisCylinder")
FColor Colour;
FStevesEditorVisCylinder(const FVector& InLocation, float InHeight, float InRadius, const FRotator& InRot,
const FColor& InColour) :
Location(InLocation),
Height(InHeight),
Radius(InRadius),
Rotation(InRot),
Colour(InColour)
{
}
FStevesEditorVisCylinder():
Location(FVector::ZeroVector),
Height(50),
Radius(10),
Rotation(FRotator::ZeroRotator),
Colour(FColor::White)
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisCapsule : public FStevesEditorVisCylinder
{
GENERATED_BODY()
FStevesEditorVisCapsule(const FVector& InLocation, float InHeight, float InRadius, const FRotator& InRot,
const FColor& InColour) : FStevesEditorVisCylinder(InLocation, InHeight, InRadius, InRot, InColour)
{
}
FStevesEditorVisCapsule() : FStevesEditorVisCylinder()
{
}
};
USTRUCT(BlueprintType)
struct STEVESUEHELPERS_API FStevesEditorVisMesh
{
GENERATED_BODY()
/// The mesh do display
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
TObjectPtr<UStaticMesh> Mesh;
/// Location relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
FVector Location;
/// Scale of the mesh compared to component scale
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
FVector Scale;
/// Rotation relative to component
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
FRotator Rotation;
/// The colour of the line render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
FColor Colour;
/// Whether to use the lowest detail LOD for vis
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisMesh")
bool bUseLowestLOD = true;
FStevesEditorVisMesh(UStaticMesh* InMesh,
const FVector& InLocation,
const FVector& InScale,
const FRotator& InRot,
const FColor& InColour,
bool InUseLowestLOD = true) :
Mesh(InMesh),
Location(InLocation),
Scale(InScale),
Rotation(InRot),
Colour(InColour),
bUseLowestLOD(InUseLowestLOD)
{
}
FStevesEditorVisMesh() : Mesh(nullptr),
Location(FVector::ZeroVector),
Scale(FVector::OneVector),
Rotation(FRotator::ZeroRotator),
Colour(FColor::White)
{
}
};
/**
*
* A component that solely exists to provide arbitrary editor visualisation when not selected.
* FComponentVisualizer can only display visualisation when selected.
* To display vis on an unselected object, you need a UPrimitiveComponent, and sometimes you don't want/need one of those
* in your actor. Instead, add UStevesEditorVisComponent at construction of your actor, or registration of another component,
* but only in a WITH_EDITOR block. Then, get nice visualisation of your actor/component without making more invasive changes
* to your code.
*
* If you want to, you can add this to your Blueprints too. This component automatically marks itself as "visualisation
* only" so shouldn't have a runtime impact.
*/
UCLASS(Blueprintable, ClassGroup="Utility", hidecategories=(Collision,Physics,Object,LOD,Lighting,TextureStreaming),
meta=(DisplayName="Steves Editor Visualisation", BlueprintSpawnableComponent))
class STEVESUEHELPERS_API UStevesEditorVisComponent : public UPrimitiveComponent
{
GENERATED_BODY()
public:
/// Circles to render
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisLine> Lines;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisLine> Arrows;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisCircle> Circles;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisArc> Arcs;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisSphere> Spheres;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisBox> Boxes;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisCylinder> Cylinders;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisCapsule> Capsules;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="StevesVisComponent")
TArray<FStevesEditorVisMesh> Meshes;
UStevesEditorVisComponent(const FObjectInitializer& ObjectInitializer);
virtual FPrimitiveSceneProxy* CreateSceneProxy() override;
virtual FBoxSphereBounds CalcBounds(const FTransform& LocalToWorld) const override;
/// Needs to update on transform since proxy is detached
virtual bool ShouldRecreateProxyOnUpdateTransform() const override { return true; }
};