diff --git a/Config/DefaultEditor.ini b/Config/DefaultEditor.ini index e69de29..f38756e 100644 --- a/Config/DefaultEditor.ini +++ b/Config/DefaultEditor.ini @@ -0,0 +1,2 @@ +[/Script/AdvancedPreviewScene.SharedProfiles] + diff --git a/Content/Asset/Effect/Common/Module/DeadClock.uasset b/Content/Asset/Effect/Common/Module/DeadClock.uasset new file mode 100644 index 0000000..3db3e36 Binary files /dev/null and b/Content/Asset/Effect/Common/Module/DeadClock.uasset differ diff --git a/Content/Asset/Effect/Niagara/HitChannel.uasset b/Content/Asset/Effect/Niagara/HitChannel.uasset index 24f381b..d02267d 100644 Binary files a/Content/Asset/Effect/Niagara/HitChannel.uasset and b/Content/Asset/Effect/Niagara/HitChannel.uasset differ diff --git a/Content/Asset/Effect/Niagara/HitSystem.uasset b/Content/Asset/Effect/Niagara/HitSystem.uasset index 9955e4b..4330791 100644 Binary files a/Content/Asset/Effect/Niagara/HitSystem.uasset and b/Content/Asset/Effect/Niagara/HitSystem.uasset differ diff --git a/Content/Asset/Effect/Niagara/NDCSystem.uasset b/Content/Asset/Effect/Niagara/NDCSystem.uasset index eed569f..c41afba 100644 Binary files a/Content/Asset/Effect/Niagara/NDCSystem.uasset and b/Content/Asset/Effect/Niagara/NDCSystem.uasset differ diff --git a/Content/BP/Char/FXCharacter.uasset b/Content/BP/Char/FXCharacter.uasset index 28d3a4b..1c0fe78 100644 Binary files a/Content/BP/Char/FXCharacter.uasset and b/Content/BP/Char/FXCharacter.uasset differ diff --git a/Source/zworld/CrashActor.cpp b/Source/zworld/CrashActor.cpp index 2627e55..4507e81 100644 --- a/Source/zworld/CrashActor.cpp +++ b/Source/zworld/CrashActor.cpp @@ -22,16 +22,105 @@ void TestCrash(int CrashFrame) { }; FN(); } +ETestCrashType CrashNameToEnum(const FString& CrashName) { + UEnum* CrashEnumPtr = nullptr; + if (!CrashEnumPtr) + { + CrashEnumPtr = FindObject(ANY_PACKAGE, TEXT("ETestCrashType"), true); + } + if (!CrashEnumPtr) + { + return ETestCrashType::NullPointer; + } + return static_cast(CrashEnumPtr->GetValueByNameString(CrashName)); +} +void CrashTest(FString CrashName) { + ETestCrashType Type = CrashNameToEnum(CrashName); + switch (Type) + { + case ETestCrashType::NullPointer: + { + volatile char* ptr = nullptr; + *ptr += 1; + } + break; + case ETestCrashType::ArrayOutOfBounds: + { + TArray emptyArray; + emptyArray[0] = 10; + } + break; + case ETestCrashType::BadFunctionPtr: + { + void(*funcPointer)() = nullptr; + funcPointer(); + } + break; + case ETestCrashType::IllegalAccess: + { + int* addrPtr = reinterpret_cast(0x12345678); + *addrPtr = 10; + } + break; + case ETestCrashType::StackOverflow: + { + using CrashRecursiveFnType = void (*)(int counter); + static CrashRecursiveFnType CrashFn; + CrashFn = [](int counter) + { + volatile int data[1024]; // 每次递归分配额外栈空间加速溢出 + UE_LOG(LogTemp, Warning, TEXT("Depth: %d"), counter); + CrashFn(data[0] + 1); // 无限递归 + }; + CrashFn(1); + } + break; + case ETestCrashType::CrashOOM: + { + // 持续分配内存直到崩溃 + TArray MemoryBlocks; + while (true) + { + // 每次分配 100MB(调整数值适配测试环境) + void* Block = FMemory::Malloc(100 * 1024 * 1024); + if (!Block) + { + // 分配失败时主动崩溃或记录日志 + UE_LOG(LogTemp, Fatal, TEXT("OOM崩溃触发!")); + break; + } + MemoryBlocks.Add(Block); + } + } + break; + case ETestCrashType::Assert: + { + char* assertPtr = nullptr; + check(assertPtr != nullptr); + } + break; + case ETestCrashType::Ensure: + { + char* ensurePtr = nullptr; + ensure(ensurePtr != nullptr); + } + break; + default: + { + UE_LOG(LogTemp, Warning, TEXT("Uknown app termination type!")); + } + break; + } +} // Called every frame void ACrashActor::Tick(float DeltaTime) { Super::Tick(DeltaTime); - CrashFrame = 200; + CrashFrame = 100; if (Frame++ >= CrashFrame) { - if (Frame == CrashFrame + 100) { - UE_LOG(LogTemp, Error, TEXT("ACrashActor:BeforeCrash")); - TestCrash(CrashFrame); - } + UE_LOG(LogTemp, Error, TEXT("ACrashActor:BeforeCrash")); + CrashTest("CrashOOM"); + //TestCrash(CrashFrame); } } diff --git a/Source/zworld/CrashActor.h b/Source/zworld/CrashActor.h index f58d3e3..4043ec4 100644 --- a/Source/zworld/CrashActor.h +++ b/Source/zworld/CrashActor.h @@ -5,7 +5,18 @@ #include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "CrashActor.generated.h" - +UENUM() +enum class ETestCrashType : uint8 +{ + NullPointer UMETA(DisplayName = "NullPointer"), + ArrayOutOfBounds UMETA(DisplayName = "ArrayOutOfBounds"), + BadFunctionPtr UMETA(DisplayName = "BadFunctionPtr"), + IllegalAccess UMETA(DisplayName = "IllegalAccess"), + StackOverflow UMETA(DisplayName = "StackOverflow"), + CrashOOM UMETA(DisplayName = "CrashOOM"), + Assert UMETA(DisplayName = "Assert"), + Ensure UMETA(DisplayName = "Ensure") +}; UCLASS() class ZWORLD_API ACrashActor : public AActor { diff --git a/Source/zworld/FXComponent.cpp b/Source/zworld/FXComponent.cpp index c02097d..c954e4f 100644 --- a/Source/zworld/FXComponent.cpp +++ b/Source/zworld/FXComponent.cpp @@ -6,6 +6,8 @@ #include "NiagaraComponent.h" #include "NiagaraFunctionLibrary.h" #include "NiagaraDataChannel.h" +#include "NiagaraDataChannelHandler.h" +#include "NiagaraDataChannel_Islands.h" #include "NameRegisterLibrary.h" #include "NiagaraDataChannelAccessor.h" // Sets default values for this component's properties @@ -44,7 +46,8 @@ UObject* UFXComponent::PlayFX(UObject* FXAsset, USceneComponent* MeshComp, FName FXObject = SpawnSystemAttached(NiagaraAsset, MeshComp, SocketName, LocalOffset, LocalRotation, SpawnInfo); }else if (UNiagaraDataChannelAsset* NDCAsset = Cast(FXAsset)) { - FXObject = UNiagaraDataChannelLibrary::WriteToNiagaraDataChannel(this, NDCAsset, FNiagaraDataChannelSearchParameters(GetOwner()->GetActorLocation()), DataChannelCount, + FNiagaraDataChannelSearchParameters SearchParams = (GetOwner()->GetActorLocation()); + FXObject = UNiagaraDataChannelLibrary::WriteToNiagaraDataChannel(this, NDCAsset, SearchParams, DataChannelCount, true, true, true, *GetOwner()->GetName()); if (auto NDCWriter = Cast(FXObject)) { diff --git a/Source/zworld/NiagaraArrayBatchSubsystem.cpp b/Source/zworld/NiagaraArrayBatchSubsystem.cpp new file mode 100644 index 0000000..6605f6d --- /dev/null +++ b/Source/zworld/NiagaraArrayBatchSubsystem.cpp @@ -0,0 +1,1020 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "NiagaraArrayBatchSubsystem.h" +#include "NiagaraComponent.h" +#include "NiagaraDataInterfaceArrayFunctionLibrary.h" +#include "NiagaraFunctionLibrary.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogZBS, Log, All); + +DEFINE_LOG_CATEGORY(LogZBS); + +const FName UNiagaraArrayBatchSubsystem::ParticleIDName = TEXT("User.SpawnList"); +const FName UNiagaraArrayBatchSubsystem::PositionParamName = TEXT("User.Positions"); +const FName UNiagaraArrayBatchSubsystem::RotationParamName = TEXT("User.Rotations"); +const FName UNiagaraArrayBatchSubsystem::ColorParamName = TEXT("User.Colors"); +const FName UNiagaraArrayBatchSubsystem::TextureParamName = TEXT("User.TextureIndices"); +const FName UNiagaraArrayBatchSubsystem::DeadTimeName = TEXT("User.DeadTimes"); + +template +FORCEINLINE TArray ConvertBatchDataToArray(const TArray>& InArray) +{ + TArray Result; + Result.Reserve(InArray.Num()); + for (const auto& Data : InArray) + { + Result.Add(Data.Data); + } + return Result; +} + +FNABIsland::~FNABIsland() +{ + if (NiagaraComponent.IsValid()) + { + NiagaraComponent->ReleaseToPool(); + } + NiagaraComponent = nullptr; +} + +void FNABIsland::Init(const FVector& Extent) +{ + Bounds.Origin = FVector::ZeroVector; + Bounds.BoxExtent = Extent; +} + +void FNABIsland::Tick() +{ + if (Data.bDirty) + { + if (!IsBeingUsed()) + { + FBox HandlerSystemBounds(-Bounds.BoxExtent, Bounds.BoxExtent); + if (NiagaraSystem) + { + FFXSystemSpawnParameters SpawnParams; + SpawnParams.bAutoActivate = false;//We must activate AFTER adding this component to our handle system array. + SpawnParams.bAutoDestroy = false; + SpawnParams.Location = Bounds.Origin; + SpawnParams.PoolingMethod = EPSCPoolMethod::ManualRelease; + SpawnParams.bPreCullCheck = false; + SpawnParams.SystemTemplate = NiagaraSystem; + SpawnParams.WorldContextObject = Subsystem.Get(); + if (UNiagaraComponent* NewComp = UNiagaraFunctionLibrary::SpawnSystemAtLocationWithParams(SpawnParams)) + { + NiagaraComponent = NewComp; + Data.NiagaraComponent = NewComp; + NewComp->SetSystemFixedBounds(HandlerSystemBounds); + NewComp->Activate(); + } + } + else + { + UE_LOG(LogZBS, Error, TEXT("NiagaraSystem is null, unable to spawn system at location")); + } + } + Data.ConsumeData(); + } +} + +void FNABIsland::OnAcquired(UObject* WorldContext, FVector Location) +{ + FVector ActualMaxSize = Bounds.BoxExtent; + FVector BoxSize = Bounds.BoxExtent * 2; + FVector BoxN = Location / BoxSize; + BoxN.X = FMath::RoundToNegativeInfinity(BoxN.X); + BoxN.Y = FMath::RoundToNegativeInfinity(BoxN.Y); + BoxN.Z = FMath::RoundToNegativeInfinity(BoxN.Z); + Bounds.Origin = BoxN * BoxSize + Bounds.BoxExtent; + Bounds.BoxExtent = ActualMaxSize; + Subsystem = Cast(WorldContext); + + // FBox HandlerSystemBounds(-Bounds.BoxExtent, Bounds.BoxExtent); + // if(NiagaraSystem) + // { + // FFXSystemSpawnParameters SpawnParams; + // SpawnParams.bAutoActivate = false;//We must activate AFTER adding this component to our handle system array. + // SpawnParams.bAutoDestroy = false; + // SpawnParams.Location = Bounds.Origin; + // SpawnParams.PoolingMethod = EPSCPoolMethod::ManualRelease; + // SpawnParams.bPreCullCheck = false; + // SpawnParams.SystemTemplate = NiagaraSystem; + // SpawnParams.WorldContextObject = WorldContext; + // if(UNiagaraComponent* NewComp = UNiagaraFunctionLibrary::SpawnSystemAtLocationWithParams(SpawnParams)) + // { + // NiagaraComponent = NewComp; + // Data.NiagaraComponent = NewComp; + // NewComp->SetSystemFixedBounds(HandlerSystemBounds); + // NewComp->Activate(); + // } + // } +} + +void FNABIsland::OnReleased() +{ + if (NiagaraComponent.IsValid()) + { + NiagaraComponent->ReleaseToPool(); + } + NiagaraComponent = nullptr; +} + +bool FNABIsland::IsBeingUsed() const +{ + if (!NiagaraComponent.IsValid()) + { + return false; + } + return NiagaraComponent->IsActive(); +} + +void FNABIslandInfo::Tick(float DeltaTime) +{ + for (auto Iter = ActiveIslands.CreateIterator(); Iter; ++Iter) + { + FNABIsland& Island = IslandPool[*Iter]; + if (!Island.IsBeingUsed() && !Island.IsDirty()) + { + Island.OnReleased(); + FreeIslands.Add(*Iter); + Iter.RemoveCurrent(); + } + else + { + Island.Tick(); + } + } +} + +void FNiagaraArrayBatchData::ConsumeData() +{ + QUICK_SCOPE_CYCLE_COUNTER(NiagaraArrayBatchData_ConsumeData); + + bDirty = false; + + if (!NiagaraComponent.IsValid()) + { + return; + } + + for (const auto& Data : VectorData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : FloatData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayFloat(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : IntData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayInt32(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : ColorData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayColor(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : QuatData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayQuat(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : BoolData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayBool(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } + for (const auto& Data : Vector2DData) + { + UNiagaraDataInterfaceArrayFunctionLibrary::SetNiagaraArrayVector2D(NiagaraComponent.Get(), Data.Key, ConvertBatchDataToArray(Data.Value)); + } +} + +void UNiagaraArrayBatchSubsystem::Tick(float DeltaTime) +{ + QUICK_SCOPE_CYCLE_COUNTER(NiagaraArrayBatchSubsystem_Tick); + + Super::Tick(DeltaTime); + + for (auto Iter = NiagaraIslandInfoMap.CreateIterator(); Iter; ++Iter) + { + if (!Iter->Key.IsValid()) + { + Iter.RemoveCurrent(); + continue; + } + Iter->Value.Tick(DeltaTime); + } +} + +FNABIsland* UNiagaraArrayBatchSubsystem::FindOrCreateIsland(UNiagaraSystem* NiagaraSystem, const FVector& Location, int32& IslandIndex) +{ + //Find the first island that could contain this point. + //For now we do a linear search of active islands. + //Assuming that overall active island count will be low. + //If this is not the case then we'll want to add an acceleration structure to speed up this search. + if (!bLoadedIslandExtents) + { + bLoadedIslandExtents = true; + NiagaraIslandExtentsMap = GetNiagaraIslandExtents(); + } + auto& NABIslandInfo = NiagaraIslandInfoMap.FindOrAdd(NiagaraSystem); + if (FVector* Ret = NiagaraIslandExtentsMap.Find(NiagaraSystem->GetPackage()->GetPathName())) + { + NABIslandInfo.Extent = *Ret; + } + + FNABIsland* IslandToUse = nullptr; + for (int32 i : NABIslandInfo.ActiveIslands) + { + FNABIsland& Island = NABIslandInfo.IslandPool[i]; + if (Island.Contains(Location)) + { + IslandToUse = &Island; + IslandIndex = i; + } + } + + if (IslandToUse) + { + return IslandToUse; + } + + //Failing that, get a init a new island from the pool. + int32 NewIslandIndex = ActivateNewIsland(NiagaraSystem, NABIslandInfo, Location); + if (ensure(NewIslandIndex != INDEX_NONE)) + { + IslandToUse = &NABIslandInfo.IslandPool[NewIslandIndex]; + IslandIndex = NewIslandIndex; + } + + if (IslandToUse) + { + IslandToUse->OnAcquired(this, Location); + } + + return IslandToUse; +} + +int32 UNiagaraArrayBatchSubsystem::ActivateNewIsland(UNiagaraSystem* NiagaraSystem, FNABIslandInfo& FNABIslandInfo, FVector Location) +{ + int32 NewIndex = INDEX_NONE; + FNABIsland* NewIsland = nullptr; + if (FNABIslandInfo.FreeIslands.Num() > 0) + { + NewIndex = FNABIslandInfo.FreeIslands.Pop(false); + NewIsland = &FNABIslandInfo.IslandPool[NewIndex]; + } + + if (NewIsland == nullptr) + { + NewIndex = FNABIslandInfo.IslandPool.Num(); + NewIsland = &FNABIslandInfo.IslandPool.AddDefaulted_GetRef(); + } + + if (NewIndex != INDEX_NONE) + { + check(NewIsland); + FNABIslandInfo.ActiveIslands.Add(NewIndex); + NewIsland->NiagaraSystem = NiagaraSystem; + NewIsland->Init(FNABIslandInfo.Extent); + } + + return NewIndex; +} +int64 FNABParticleData::GetUUID() +{ + return static_cast(IslandIndex) << 32 | ParticleID; +} + +TArray& FNABParticleData::GetPropertys() +{ + return Propertys; +} + +FNABParticleData& FNABParticleData::WriteVector(FName Name, const FVector& Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Vector, Name }); + DataPtr->VectorData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData& FNABParticleData::WriteQuat(FName Name, const FQuat& Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Quat, Name }); + DataPtr->QuatData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData& FNABParticleData::WriteColor(FName Name, const FLinearColor& Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Color, Name }); + DataPtr->ColorData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData& FNABParticleData::WriteInt(FName Name, int32 Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Int32, Name }); + DataPtr->IntData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData& FNABParticleData::WriteFloat(FName Name, float Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Float, Name }); + DataPtr->FloatData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData& FNABParticleData::WriteBool(FName Name, bool Value) +{ + if (DataPtr) + { + Propertys.Add(FNiagaraBatchProperty{ ENiagaraBatchDataType::Bool, Name }); + DataPtr->BoolData.FindOrAdd(Name).Add({ ParticleID, Value }); + DataPtr->bDirty = true; + } + return *this; +} + +FNABParticleData UNiagaraArrayBatchSubsystem::WriteNABParticle(UNiagaraSystem* NiagaraAsset, const FVector& Location) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + return FNABParticleData{ DataUid , IslandIndex , &Data }.WriteInt(ParticleIDName, DataUid); +} + +template +void RemoveProperty(TMap>>& Data, FName Name, int64 DataUid) +{ + Data.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveNABParticle(UNiagaraSystem* NiagaraAsset, int64 DataUid, const TArray& Propertys) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + for (auto& Property : Propertys) + { + ENiagaraBatchDataType Type = Property.Type; + FName Name = Property.Name; + switch (Type) + { + case ENiagaraBatchDataType::Vector: + RemoveProperty(Data.VectorData, Name, DataUid); + break; + case ENiagaraBatchDataType::Float: + RemoveProperty(Data.FloatData, Name, DataUid); + break; + case ENiagaraBatchDataType::Int32: + RemoveProperty(Data.IntData, Name, DataUid); + break; + case ENiagaraBatchDataType::Color: + RemoveProperty(Data.ColorData, Name, DataUid); + break; + case ENiagaraBatchDataType::Quat: + RemoveProperty(Data.QuatData, Name, DataUid); + break; + case ENiagaraBatchDataType::Bool: + RemoveProperty(Data.BoolData, Name, DataUid); + break; + case ENiagaraBatchDataType::Vector2D: + RemoveProperty(Data.Vector2DData, Name, DataUid); + break; + default: + ensureMsgf(false, TEXT("%s Failed to remove property %d %s"), *NiagaraAsset->GetName(), Type, *Name.ToString()); + } + } +} + +void UNiagaraArrayBatchSubsystem::WriteNABVector(FNABParticleData& Data, FName Name, const FVector& Value) +{ + Data.WriteVector(Name, Value); +} + +void UNiagaraArrayBatchSubsystem::WriteNABQuat(FNABParticleData& Data, FName Name, const FQuat& Value) +{ + Data.WriteQuat(Name, Value); +} + +void UNiagaraArrayBatchSubsystem::WriteNABColor(FNABParticleData& Data, FName Name, const FLinearColor& Value) +{ + Data.WriteColor(Name, Value); +} + +void UNiagaraArrayBatchSubsystem::WriteNABInt(FNABParticleData& Data, FName Name, int32 Value) +{ + Data.WriteInt(Name, Value); +} + +void UNiagaraArrayBatchSubsystem::WriteNABFloat(FNABParticleData& Data, FName Name, float Value) +{ + Data.WriteFloat(Name, Value); +} + +void UNiagaraArrayBatchSubsystem::WriteNABBool(FNABParticleData& Data, FName Name, bool Value) +{ + Data.WriteBool(Name, Value); +} + +int64 UNiagaraArrayBatchSubsystem::WriteVector(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, const FVector& Value) +{ + if (!NiagaraAsset) + { + return 0; + } + + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.VectorData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteFloat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + float Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.FloatData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteInt(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + int32 Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.IntData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteColor(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + const FLinearColor& Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.ColorData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteQuat(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + const FQuat& Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.QuatData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteBool(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + bool Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.BoolData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +int64 UNiagaraArrayBatchSubsystem::WriteVector2D(UNiagaraSystem* NiagaraAsset, const FVector& Location, FName Name, + const FVector2D& Value) +{ + if (!NiagaraAsset) + { + return 0; + } + int32 IslandIndex; + auto* Island = FindOrCreateIsland(NiagaraAsset, Location, IslandIndex); + if (!ensureMsgf(Island, TEXT("Failed to find or create island for %s"), *NiagaraAsset->GetName())) + { + return 0; + } + + auto DataUid = ++Island->DataUid; + FNiagaraArrayBatchData& Data = Island->Data; + Data.Vector2DData.FindOrAdd(Name).Add({ DataUid, Value }); + Data.bDirty = true; + + return static_cast(IslandIndex) << 32 | DataUid; +} + +void UNiagaraArrayBatchSubsystem::OverrideVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, + const FVector& Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.VectorData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::OverrideFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, float Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.FloatData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid);; + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::OverrideInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, int32 Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.IntData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid);; + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::OverrideColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, + const FLinearColor& Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.ColorData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid);; + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::OverrideQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, + const FQuat& Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.QuatData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid);; + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::OverrideBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid, bool Value) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.BoolData.FindOrAdd(Name).FindByPredicate([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid);; + })->Data = Value; +} + +void UNiagaraArrayBatchSubsystem::RemoveVector(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.VectorData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveFloat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.FloatData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveInt(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.IntData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveColor(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.ColorData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveQuat(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (DataUid == 0) + { + return; + } + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.QuatData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveBool(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.BoolData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::RemoveVector2D(UNiagaraSystem* NiagaraAsset, FName Name, int64 DataUid) +{ + if (!NiagaraAsset) + { + return; + } + int32 IslandIndex = DataUid >> 32; + auto* IslandInfo = NiagaraIslandInfoMap.Find(NiagaraAsset); + if (!ensureMsgf(IslandInfo, TEXT("Failed to find island for %s"), *NiagaraAsset->GetName())) + { + return; + } + if (!IslandInfo->IslandPool.IsValidIndex(IslandIndex)) + { + return; + } + auto& Island = IslandInfo->IslandPool[IslandIndex]; + FNiagaraArrayBatchData& Data = Island.Data; + Data.bDirty = true; + Data.Vector2DData.FindOrAdd(Name).RemoveAll([DataUid](const FNiagaraBatchData& InData) + { + return InData.DataUid == static_cast(DataUid); + }); +} + +void UNiagaraArrayBatchSubsystem::SetNiagaraHidden(const FString& NiagaraFullName, bool bHide, FName HideTag) +{ + for (auto& Pair : NiagaraIslandInfoMap) + { + if (!Pair.Key.IsValid()) + { + continue; + } + if (Pair.Key->GetPathName() == NiagaraFullName) + { + for (auto& Island : Pair.Value.IslandPool) + { + if (!Island.NiagaraComponent.IsValid()) + { + continue; + } + //TArray HiddenComponents; + //URuntimeCommonFunctionLibrary::SetSceneComponentHiddenInGame(Island.NiagaraComponent.Get(), bHide, false, HideTag, HiddenComponents); + } + break; + } + } +} diff --git a/Source/zworld/NiagaraArrayBatchSubsystem.h b/Source/zworld/NiagaraArrayBatchSubsystem.h new file mode 100644 index 0000000..123a4cd --- /dev/null +++ b/Source/zworld/NiagaraArrayBatchSubsystem.h @@ -0,0 +1,289 @@ +// 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; +}; diff --git a/Source/zworld/zworld.Build.cs b/Source/zworld/zworld.Build.cs index e503b75..e218f7e 100644 --- a/Source/zworld/zworld.Build.cs +++ b/Source/zworld/zworld.Build.cs @@ -11,7 +11,7 @@ public class zworld : ModuleRules PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "EnhancedInput" ,"Niagara"}); - PrivateDependencyModuleNames.AddRange(new string[] { "UnLua" }); + PrivateDependencyModuleNames.AddRange(new string[] { "UnLua", "Sentry" }); // Uncomment if you are using Slate UI // PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });