// Fill out your copyright notice in the Description page of Project Settings. #pragma once #include "CoreMinimal.h" #include "UnLuaInterface.h" #include "Subsystems/WorldSubsystem.h" #include "NiagaraComponent.h" #include "NiagaraArrayBatchSubsystem.generated.h" class UNiagaraDataChannelHandler_Islands; class UNiagaraSystem; class UNiagaraComponent; template struct FNiagaraBatchData { FNiagaraBatchData(uint32 InDataUid, T InData) : DataUid(InDataUid) , Data(InData) { } uint32 DataUid; T Data; }; UENUM(BlueprintType) enum class ENiagaraBatchDataType : uint8 { Vector, Float, Int32, Color, Quat, Bool, Vector2D, }; USTRUCT(BlueprintType) struct FNiagaraBatchProperty { GENERATED_BODY() ENiagaraBatchDataType Type; FName Name; }; struct FNiagaraArrayBatchData { friend class UNiagaraArrayBatchSubsystem; friend struct FNABParticleData; friend struct FNABIsland; private: void ConsumeData(); private: TWeakObjectPtr NiagaraComponent; TMap>> VectorData; TMap>> FloatData; TMap>> IntData; TMap>> ColorData; TMap>> QuatData; TMap>> BoolData; TMap>> Vector2DData; bool bDirty = false; }; USTRUCT() struct FNABIsland { GENERATED_BODY() // UE_NONCOPYABLE(FNABIsland) friend class UNiagaraArrayBatchSubsystem; public: FNABIsland() {}; ~FNABIsland(); void Init(const FVector& Extent); void Tick(); FORCEINLINE bool Contains(FVector Point) const { return Bounds.ComputeSquaredDistanceFromBoxToPoint(Point) <= 0.f; } void OnAcquired(UObject* WorldContext, FVector Location); void OnReleased(); bool IsBeingUsed() const; FORCEINLINE bool IsDirty() const { return Data.bDirty; } private: /** Current bounds of this island. The bounds of any handler systems are modified to match these bounds. */ UPROPERTY() FBoxSphereBounds Bounds = FBoxSphereBounds(EForceInit::ForceInit); /** Niagara components spawned for this island. */ UPROPERTY() TWeakObjectPtr NiagaraComponent = nullptr; UPROPERTY() UNiagaraSystem* NiagaraSystem = nullptr; /** The underlying storage for this island. */ FNiagaraArrayBatchData Data; uint32 DataUid = 0; TWeakObjectPtr Subsystem = nullptr; }; USTRUCT() struct FNABIslandInfo { GENERATED_BODY() void Tick(float DeltaTime); /** All currently active Islands for this channel. */ UPROPERTY() TArray ActiveIslands; /** All currently free Islands for this channel. */ UPROPERTY() TArray FreeIslands; /** Pool of all islands. */ UPROPERTY() TArray IslandPool; UPROPERTY() FVector Extent = FVector(5000.f, 5000.f, 2000.f); }; USTRUCT(BlueprintType) struct FNABParticleData { GENERATED_BODY() uint32 ParticleID; int32 IslandIndex; FNiagaraArrayBatchData* DataPtr; TArray Propertys; public: FNABParticleData() : FNABParticleData(0) { } FNABParticleData(uint32 ParticleID) : ParticleID(ParticleID), IslandIndex(0), DataPtr(nullptr) { } FNABParticleData(uint32 ParticleID, int32 IslandIndex, FNiagaraArrayBatchData* DataPtr) : ParticleID(ParticleID), IslandIndex(IslandIndex), DataPtr(DataPtr) { } int64 GetUUID(); TArray& GetPropertys(); FNABParticleData& WriteVector(FName Name, const FVector& Value); FNABParticleData& WriteQuat(FName Name, const FQuat& Value); FNABParticleData& WriteColor(FName Name, const FLinearColor& Value); FNABParticleData& WriteInt(FName Name, int32 Value); FNABParticleData& WriteFloat(FName Name, float Value); FNABParticleData& WriteBool(FName Name, bool Value); }; /** * */ UCLASS() class ZWORLD_API UNiagaraArrayBatchSubsystem : public UTickableWorldSubsystem, public IUnLuaInterface { GENERATED_BODY() virtual FString GetModuleName_Implementation() const override { return TEXT("BluePrints.Managers.NiagaraArrayBatchSubsystem_C"); } virtual TStatId GetStatId() const override { RETURN_QUICK_DECLARE_CYCLE_STAT(UNiagaraArrayBatchSubsystem, STATGROUP_Tickables); } public: static const FName ParticleIDName; static const FName PositionParamName; static const FName RotationParamName; static const FName TextureParamName; static const FName ColorParamName; static const FName DeadTimeName; UFUNCTION(BlueprintCallable) FNABParticleData WriteNABParticle(UNiagaraSystem* NiagaraAsset, const FVector& Location); UFUNCTION(BlueprintCallable) void RemoveNABParticle(UNiagaraSystem* NiagaraAsset, int64 DataUid, const TArray& Propertys); UFUNCTION(BlueprintCallable) void WriteNABVector(FNABParticleData& Data, FName Name, const FVector& Value); UFUNCTION(BlueprintCallable) void WriteNABQuat(FNABParticleData& Data, FName Name, const FQuat& Value); UFUNCTION(BlueprintCallable) void WriteNABColor(FNABParticleData& Data, FName Name, const FLinearColor& Value); UFUNCTION(BlueprintCallable) void WriteNABInt(FNABParticleData& Data, FName Name, int32 Value); UFUNCTION(BlueprintCallable) void WriteNABFloat(FNABParticleData& Data, FName Name, float Value); UFUNCTION(BlueprintCallable) void WriteNABBool(FNABParticleData& Data, FName Name, bool Value); UFUNCTION(BlueprintCallable) int64 WriteVector(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector& Value); UFUNCTION(BlueprintCallable) int64 WriteFloat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, float Value); UFUNCTION(BlueprintCallable) int64 WriteInt(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, int32 Value); UFUNCTION(BlueprintCallable) int64 WriteColor(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FLinearColor& Value); UFUNCTION(BlueprintCallable) int64 WriteQuat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FQuat& Value); UFUNCTION(BlueprintCallable) int64 WriteBool(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, bool Value); UFUNCTION(BlueprintCallable) int64 WriteVector2D(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector2D& Value); UFUNCTION(BlueprintCallable) void OverrideVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FVector& Value); UFUNCTION(BlueprintCallable) void OverrideFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, float Value); UFUNCTION(BlueprintCallable) void OverrideInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, int32 Value); UFUNCTION(BlueprintCallable) void OverrideColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FLinearColor& Value); UFUNCTION(BlueprintCallable) void OverrideQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, const FQuat& Value); UFUNCTION(BlueprintCallable) void OverrideBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, bool Value); UFUNCTION(BlueprintCallable) void RemoveVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void RemoveVector2D(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid); UFUNCTION(BlueprintCallable) void SetNiagaraHidden(const FString& NiagaraFullName, bool bHide, FName HideTag); protected: virtual void Tick(float DeltaTime) override; /** Gets the correct island for the given location. */ FNABIsland* FindOrCreateIsland(UNiagaraSystem* NiagaraSystem, const FVector& Location, int32& IslandIndex); /** Initializes and adds a new island to the ActiveIslands list. Either retrieving from the free pool of existing inactive islands or creating a new one. */ int32 ActivateNewIsland(UNiagaraSystem* NiagaraSystem, FNABIslandInfo& FNABIslandInfo, FVector Location); UFUNCTION(BlueprintImplementableEvent) TMap GetNiagaraIslandExtents(); protected: UPROPERTY() TMap, FNABIslandInfo> NiagaraIslandInfoMap; UPROPERTY() TMap NiagaraIslandExtentsMap; bool bLoadedIslandExtents = false; };