CelticCraft/Plugins/VoxelFree/Source/Voxel/Public/VoxelComponents/VoxelInvokerComponent.h

239 lines
9.5 KiB
C
Raw Normal View History

2023-07-03 16:17:13 +00:00
// Copyright 2020 Phyronnaz
#pragma once
#include "CoreMinimal.h"
#include "VoxelIntBox.h"
#include "Components/SceneComponent.h"
#include "GameFramework/Volume.h"
#include "VoxelInvokerSettings.h"
#include "VoxelInvokerComponent.generated.h"
class AVoxelWorldInterface;
// Voxel Invokers are used to configure the voxel world LOD, collisions and navmesh
UCLASS(Abstract, Blueprintable, ClassGroup = Voxel)
class VOXEL_API UVoxelInvokerComponentBase : public USceneComponent
{
GENERATED_BODY()
public:
// Whether or not this invoker will be used to trigger voxel events
// Example of voxel events include:
// - foliage spawning
// - foliage collisions
// - manually bound events
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Events")
bool bUseForEvents = true;
// Whether to use to compute the tasks priorities
// If true, the task priorities will be higher if they are closer to this
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Priority")
bool bUseForPriorities = true;
protected:
// Whether to enable the invoker when spawned
// If not, you'll need to call EnableInvoker
UPROPERTY(EditDefaultsOnly, Category = "Voxel Invoker")
bool bStartsEnabled = true;
public:
// Is this invoker local? If false, bUseForLOD will always be considered as false
// Useful for multiplayer, to only compute the LOD for the local player
// Defaults to Cast<APawn>(GetOwner())->IsLocallyControlled()
UFUNCTION(BlueprintNativeEvent, Category = "Voxel|Invoker")
bool IsLocalInvoker() const;
// Used to detect if the invoker has moved
// Also used for events
UFUNCTION(BlueprintNativeEvent, Category = "Voxel|Invoker")
FIntVector GetInvokerVoxelPosition(AVoxelWorldInterface* VoxelWorld) const;
FIntVector GetInvokerVoxelPosition(const AVoxelWorldInterface* VoxelWorld) const;
// Get the invoker settings
// All the bounds are in voxel space
UFUNCTION(BlueprintNativeEvent, Category = "Voxel|Invoker")
FVoxelInvokerSettings GetInvokerSettings(AVoxelWorldInterface* VoxelWorld) const;
FVoxelInvokerSettings GetInvokerSettings(const AVoxelWorldInterface* VoxelWorld) const;
public:
//~ Begin UVoxelInvokerComponentBase Interface
virtual bool IsLocalInvoker_Implementation() const;
virtual FIntVector GetInvokerVoxelPosition_Implementation(AVoxelWorldInterface* VoxelWorld) const;
virtual FVoxelInvokerSettings GetInvokerSettings_Implementation(AVoxelWorldInterface* VoxelWorld) const;
//~ End UVoxelInvokerComponentBase Interface
public:
UFUNCTION(BlueprintCallable, Category = "Voxel|Invoker")
void EnableInvoker();
UFUNCTION(BlueprintCallable, Category = "Voxel|Invoker")
void DisableInvoker();
UFUNCTION(BlueprintCallable, Category = "Voxel|Invoker")
bool IsInvokerEnabled() const;
protected:
//~ Begin UActorComponent Interface
virtual void OnRegister() override;
virtual void OnUnregister() override;
//~ End UActorComponent Interface
private:
bool bIsInvokerEnabled = false;
public:
UFUNCTION(BlueprintCallable, Category = "Voxel|Invoker")
static void RefreshAllVoxelInvokers();
static const TArray<TWeakObjectPtr<UVoxelInvokerComponentBase>>& GetInvokers(UWorld* World);
static FSimpleMulticastDelegate OnForceRefreshInvokers;
private:
static TMap<TWeakObjectPtr<UWorld>, TArray<TWeakObjectPtr<UVoxelInvokerComponentBase>>> Components;
};
// Voxel Invokers are used to configure the voxel world LOD, collisions and navmesh
// Simple position based invoker
UCLASS(ClassGroup = Voxel, meta = (BlueprintSpawnableComponent))
class VOXEL_API UVoxelSimpleInvokerComponent : public UVoxelInvokerComponentBase
{
GENERATED_BODY()
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|LOD")
bool bUseForLOD = true;
// You should leave this to 0
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|LOD", meta = (DisplayName = "LOD to Set", EditCondition = bUseForLOD, ClampMin = 0, ClampMax = 26, UIMin = 0, UIMax = 26))
int32 LODToSet = 0;
// In cm. Will set LODToSet around the invoker on this distance
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|LOD", meta = (DisplayName = "LOD Range", EditCondition = bUseForLOD, ClampMin = 0))
float LODRange = 1000;
// Will enable high res collisions around the invoker
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Collisions")
bool bUseForCollisions = true;
// In cm. Will enable high res collisions on chunks under this distance from this invoker
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Collisions", meta = (EditCondition = bUseForCollisions, ClampMin = 0))
float CollisionsRange = 1000;
// Will enable high res navmesh around the invoker
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Navmesh")
bool bUseForNavmesh = true;
// In cm. Will enable high res navmesh on chunks under this distance from this invoker
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Navmesh", meta = (EditCondition = bUseForNavmesh, ClampMin = 0))
float NavmeshRange = 1000;
public:
// VoxelSimpleInvokerComponent's GetInvokerVoxelPosition and GetInvokerSettings functions are calling GetInvokerGlobalPosition to find the global position of the invoker
// Defaults to GetComponentPosition
UFUNCTION(BlueprintNativeEvent, Category = "Voxel|Invoker")
FVector GetInvokerGlobalPosition() const;
public:
//~ Begin UVoxelInvokerComponentBase Interface
virtual FIntVector GetInvokerVoxelPosition_Implementation(AVoxelWorldInterface* VoxelWorld) const override;
virtual FVoxelInvokerSettings GetInvokerSettings_Implementation(AVoxelWorldInterface* VoxelWorld) const override;
//~ End UVoxelInvokerComponentBase Interface
protected:
//~ Begin UVoxelSimpleInvokerComponent Interface
virtual FVector GetInvokerGlobalPosition_Implementation() const;
//~ End UVoxelSimpleInvokerComponent Interface
};
// Voxel Invokers are used to configure the voxel world LOD, collisions and navmesh
// Same as simple invoker, but optionally use the velocity to predict the position
UCLASS(ClassGroup = Voxel, meta = (BlueprintSpawnableComponent))
class VOXEL_API UVoxelInvokerWithPredictionComponent : public UVoxelSimpleInvokerComponent
{
GENERATED_BODY()
public:
// Will use the speed of the owner to determine the position to use
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Prediction")
bool bEnablePrediction = false;
// Will multiply the velocity by this to get the new position
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Prediction", meta = (EditCondition = bEnablePrediction, ClampMin = 0))
float PredictionTime = 1;
protected:
//~ Begin UVoxelSimpleInvokerComponent Interface
virtual FVector GetInvokerGlobalPosition_Implementation() const override;
//~ End UVoxelSimpleInvokerComponent Interface
};
// Voxel Invokers are used to configure the voxel world LOD, collisions and navmesh
// Will find the camera and use it to set its position
UCLASS(ClassGroup = Voxel, meta = (BlueprintSpawnableComponent))
class VOXEL_API UVoxelInvokerAutoCameraComponent : public UVoxelSimpleInvokerComponent
{
GENERATED_BODY()
protected:
//~ Begin UVoxelSimpleInvokerComponent Interface
virtual FVector GetInvokerGlobalPosition_Implementation() const override;
//~ End UVoxelSimpleInvokerComponent Interface
};
UCLASS(Within = VoxelLODVolume)
class VOXEL_API UVoxelLODVolumeInvokerComponent : public UVoxelInvokerComponentBase
{
GENERATED_BODY()
public:
UVoxelLODVolumeInvokerComponent();
// Will set the LOD in the volume to a fixed value
// Note that the displayed LOD might have a higher resolution than this if another invoker is close
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Volume", DisplayName = "Use for LOD")
bool bUseForLOD = true;
// Will set the LOD in the volume to a fixed value
// Note that the displayed LOD might have a higher resolution than this if another invoker is close
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Volume", DisplayName = "LOD to Set", meta = (EditCondition = bUseForLOD))
int32 LODToSet = 0;
// Will compute high res collision in the volume
// Note that collisions might still be computed by the voxel world even if this is false
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Volume")
bool bUseForCollisions = false;
// Will compute high res navmesh in the volume
// Note that navmesh might still be computed by the voxel world even if this is false
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Voxel Invoker|Volume")
bool bUseForNavmesh = false;
protected:
//~ Begin UVoxelInvokerComponentBase Interface
virtual bool IsLocalInvoker_Implementation() const override;
virtual FIntVector GetInvokerVoxelPosition_Implementation(AVoxelWorldInterface* VoxelWorld) const override;
virtual FVoxelInvokerSettings GetInvokerSettings_Implementation(AVoxelWorldInterface* VoxelWorld) const override;
//~ End UVoxelInvokerComponentBase Interface
};
// Volume with a voxel invoker
// Sets the LOD of the voxels in a volume, or always enable collision/navmesh in a volume
UCLASS(hidecategories=(Advanced, Attachment, Collision, Volume), DisplayName = "Voxel LOD Volume")
class VOXEL_API AVoxelLODVolume : public AVolume
{
GENERATED_BODY()
public:
AVoxelLODVolume();
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Voxel")
TObjectPtr<UVoxelLODVolumeInvokerComponent> InvokerComponent;
protected:
//~ Begin UObject Interface
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
//~ End UObject Interface
};