// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "LyraIndicatorManagerComponent.h" #include "Widgets/SWidget.h" #include "Widgets/SNullWidget.h" #include "SceneView.h" #include "UObject/WeakInterfacePtr.h" #include "IndicatorDescriptor.generated.h" class UIndicatorDescriptor; class ULyraIndicatorManagerComponent; struct FIndicatorProjection { bool Project(const UIndicatorDescriptor& IndicatorDescriptor, const FSceneViewProjectionData& InProjectionData, const FVector2D& ScreenSize, FVector& ScreenPositionWithDepth); }; UENUM(BlueprintType) enum class EActorCanvasProjectionMode : uint8 { ComponentPoint, ComponentBoundingBox, ComponentScreenBoundingBox, ActorBoundingBox, ActorScreenBoundingBox }; /** * Describes and controls an active indicator. It is highly recommended that your widget implements * IActorIndicatorWidget so that it can 'bind' to the associated data. */ UCLASS(BlueprintType) class LYRAGAME_API UIndicatorDescriptor : public UObject { GENERATED_BODY() public: UIndicatorDescriptor() { } public: UFUNCTION(BlueprintCallable) UObject* GetDataObject() const { return DataObject; } UFUNCTION(BlueprintCallable) void SetDataObject(UObject* InDataObject) { DataObject = InDataObject; } UFUNCTION(BlueprintCallable) USceneComponent* GetSceneComponent() const { return Component; } UFUNCTION(BlueprintCallable) void SetSceneComponent(USceneComponent* InComponent) { Component = InComponent; } UFUNCTION(BlueprintCallable) FName GetComponentSocketName() const { return ComponentSocketName; } UFUNCTION(BlueprintCallable) void SetComponentSocketName(FName SocketName) { ComponentSocketName = SocketName; } UFUNCTION(BlueprintCallable) TSoftClassPtr GetIndicatorClass() const { return IndicatorWidgetClass; } UFUNCTION(BlueprintCallable) void SetIndicatorClass(TSoftClassPtr InIndicatorWidgetClass) { IndicatorWidgetClass = InIndicatorWidgetClass; } public: // TODO Organize this better. TWeakObjectPtr IndicatorWidget; public: UFUNCTION(BlueprintCallable) void SetAutoRemoveWhenIndicatorComponentIsNull(bool CanAutomaticallyRemove) { bAutoRemoveWhenIndicatorComponentIsNull = CanAutomaticallyRemove; } UFUNCTION(BlueprintCallable) bool GetAutoRemoveWhenIndicatorComponentIsNull() const { return bAutoRemoveWhenIndicatorComponentIsNull; } bool CanAutomaticallyRemove() const { return bAutoRemoveWhenIndicatorComponentIsNull && !IsValid(GetSceneComponent()); } public: // Layout Properties //======================= UFUNCTION(BlueprintCallable) bool GetIsVisible() const { return IsValid(GetSceneComponent()) && bVisible; } UFUNCTION(BlueprintCallable) void SetDesiredVisibility(bool InVisible) { bVisible = InVisible; } UFUNCTION(BlueprintCallable) EActorCanvasProjectionMode GetProjectionMode() const { return ProjectionMode; } UFUNCTION(BlueprintCallable) void SetProjectionMode(EActorCanvasProjectionMode InProjectionMode) { ProjectionMode = InProjectionMode; } // Horizontal alignment to the point in space to place the indicator at. UFUNCTION(BlueprintCallable) EHorizontalAlignment GetHAlign() const { return HAlignment; } UFUNCTION(BlueprintCallable) void SetHAlign(EHorizontalAlignment InHAlignment) { HAlignment = InHAlignment; } // Vertical alignment to the point in space to place the indicator at. UFUNCTION(BlueprintCallable) EVerticalAlignment GetVAlign() const { return VAlignment; } UFUNCTION(BlueprintCallable) void SetVAlign(EVerticalAlignment InVAlignment) { VAlignment = InVAlignment; } // Clamp the indicator to the edge of the screen? UFUNCTION(BlueprintCallable) bool GetClampToScreen() const { return bClampToScreen; } UFUNCTION(BlueprintCallable) void SetClampToScreen(bool bValue) { bClampToScreen = bValue; } // Show the arrow if clamping to the edge of the screen? UFUNCTION(BlueprintCallable) bool GetShowClampToScreenArrow() const { return bShowClampToScreenArrow; } UFUNCTION(BlueprintCallable) void SetShowClampToScreenArrow(bool bValue) { bShowClampToScreenArrow = bValue; } // The position offset for the indicator in world space. UFUNCTION(BlueprintCallable) FVector GetWorldPositionOffset() const { return WorldPositionOffset; } UFUNCTION(BlueprintCallable) void SetWorldPositionOffset(FVector Offset) { WorldPositionOffset = Offset; } // The position offset for the indicator in screen space. UFUNCTION(BlueprintCallable) FVector2D GetScreenSpaceOffset() const { return ScreenSpaceOffset; } UFUNCTION(BlueprintCallable) void SetScreenSpaceOffset(FVector2D Offset) { ScreenSpaceOffset = Offset; } UFUNCTION(BlueprintCallable) FVector GetBoundingBoxAnchor() const { return BoundingBoxAnchor; } UFUNCTION(BlueprintCallable) void SetBoundingBoxAnchor(FVector InBoundingBoxAnchor) { BoundingBoxAnchor = InBoundingBoxAnchor; } public: // Sorting Properties //======================= // Allows sorting the indicators (after they are sorted by depth), to allow some group of indicators // to always be in front of others. UFUNCTION(BlueprintCallable) int32 GetPriority() const { return Priority; } UFUNCTION(BlueprintCallable) void SetPriority(int32 InPriority) { Priority = InPriority; } public: ULyraIndicatorManagerComponent* GetIndicatorManagerComponent() { return ManagerPtr.Get(); } void SetIndicatorManagerComponent(ULyraIndicatorManagerComponent* InManager); UFUNCTION(BlueprintCallable) void UnregisterIndicator(); private: UPROPERTY() bool bVisible = true; UPROPERTY() bool bClampToScreen = false; UPROPERTY() bool bShowClampToScreenArrow = false; UPROPERTY() bool bOverrideScreenPosition = false; UPROPERTY() bool bAutoRemoveWhenIndicatorComponentIsNull = false; UPROPERTY() EActorCanvasProjectionMode ProjectionMode = EActorCanvasProjectionMode::ComponentPoint; UPROPERTY() TEnumAsByte HAlignment = HAlign_Center; UPROPERTY() TEnumAsByte VAlignment = VAlign_Center; UPROPERTY() int32 Priority = 0; UPROPERTY() FVector BoundingBoxAnchor = FVector(0.5, 0.5, 0.5); UPROPERTY() FVector2D ScreenSpaceOffset = FVector2D(0, 0); UPROPERTY() FVector WorldPositionOffset = FVector(0, 0, 0); private: friend class SActorCanvas; UPROPERTY() TObjectPtr DataObject; UPROPERTY() TObjectPtr Component; UPROPERTY() FName ComponentSocketName = NAME_None; UPROPERTY() TSoftClassPtr IndicatorWidgetClass; UPROPERTY() TWeakObjectPtr ManagerPtr; TWeakPtr Content; TWeakPtr CanvasHost; };