Skip to content

Instantly share code, notes, and snippets.

@erikdubbelboer
Created October 14, 2018 08:53
Show Gist options
  • Save erikdubbelboer/cd674cd29399bc9bddb9c9c8a6bd7886 to your computer and use it in GitHub Desktop.
Save erikdubbelboer/cd674cd29399bc9bddb9c9c8a6bd7886 to your computer and use it in GitHub Desktop.
Unreal Engine 4 DistributionVectorUniformParam Particle Distribution
#include "DistributionVectorUniformParam.h"
#include "Particles/ParticleSystemComponent.h"
UDistributionVectorUniformParam::UDistributionVectorUniformParam(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
FVector UDistributionVectorUniformParam::GetValue(float F, UObject* Data, int32 Extreme, struct FRandomStream* InRandomStream) const
{
FVector LocalMax = DefaultMax;
FVector LocalMin = DefaultMin;
FVector ParamMax;
bool bFoundParam = GetParamValue(Data, MaxParameterName, ParamMax);
if (bFoundParam)
{
LocalMax = ParamMax;
}
FVector ParamMin;
bFoundParam = GetParamValue(Data, MinParameterName, ParamMin);
if (bFoundParam)
{
LocalMin = ParamMin;
}
float fX = LocalMin.X + (LocalMax.X - LocalMin.X) * DIST_GET_RANDOM_VALUE(InRandomStream);
float fY = LocalMin.Y + (LocalMax.Y - LocalMin.Y) * DIST_GET_RANDOM_VALUE(InRandomStream);
float fZ = LocalMin.Z + (LocalMax.Z - LocalMin.Z) * DIST_GET_RANDOM_VALUE(InRandomStream);
return FVector(fX, fY, fZ);
}
bool UDistributionVectorUniformParam::GetParamValue(UObject* Data, FName ParamName, FVector& OutVector) const
{
bool bFoundParam = false;
UParticleSystemComponent* ParticleComp = Cast<UParticleSystemComponent>(Data);
if (ParticleComp)
{
bFoundParam = ParticleComp->GetAnyVectorParameter(ParamName, OutVector);
}
return bFoundParam;
}
#pragma once
#include "CoreMinimal.h"
#include "Distributions/DistributionVector.h"
#include "DistributionVectorUniformParam.generated.h"
UCLASS(collapsecategories, hidecategories = Object, editinlinenew)
class PROJECT_API UDistributionVectorUniformParam : public UDistributionVector
{
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere)
FName MaxParameterName;
UPROPERTY(EditAnywhere)
FName MinParameterName;
UPROPERTY(EditAnywhere)
FVector DefaultMax;
UPROPERTY(EditAnywhere)
FVector DefaultMin;
virtual FVector GetValue(float F = 0.f, UObject* Data = NULL, int32 LastExtreme = 0, struct FRandomStream* InRandomStream = NULL) const override;
virtual bool CanBeBaked() const override { return false; }
virtual bool IsPostLoadThreadSafe() const override { return true; };
public:
UDistributionVectorUniformParam();
private:
bool GetParamValue(UObject* Data, FName ParamName, FVector& OutVector) const;
};
@script526
Copy link

That's exactly what I was looking for. Nowadays it doesn't work due to the engine API changes, I have just tested it. Values make no affect to the particle system. I'll try finding the solution to fix this.

@erikdubbelboer
Copy link
Author

I'm still using the same code in my 4.24 project. Did it break in 4.25? Did you replace PROJECT_API with your own macro?

@script526
Copy link

Yes I did. 4.25. I was little bit wrong. Changing default values make effect as expected, although using parameters doesn't work. Parameters still work on the default engine instance parameters feature.

I'm passing parameters like this:

PSC->SetFloatParameter("SpawnRate", spawnRate_Inst);
PSC->SetVectorParameter("InitialVelocity", initialVelocity_Inst);
PSC->SetVectorParameter("InitialLocationMin", FVector(0.f, 0.f, 0.f));
PSC->SetVectorParameter("InitialLocationMax", initialLocationMax_Inst);

The reason is because the GetAnyVectorParameter function returns false. It successfully grabs the name and the value (but it's in a weird representation like X=0.000000000 Y=8.128e-43#DEN Z=1.18472447e-18) and then it skips the main loop returning false because the array of parameters (UseInstanceParameters) is empty.

Right here:

const TArray<struct FParticleSysParam>& UseInstanceParameters = GetAsyncInstanceParameters();
	for (int32 i = 0; i < UseInstanceParameters.Num(); i++)
	{ ...

Not sure why it works with the default instance parameters feature. Should I fill the array manually somehow?

@erikdubbelboer
Copy link
Author

To be honest I'm not sure, I always use blueprints for most of my code.

@script526
Copy link

Okay, thank you anyway!

@script526
Copy link

Erik, do you mind if we add this class to the Community Ocean Plugin (it's free and open source)?
https://github.com/UE4-OceanProject/OceanProject

I'd like to use it for controlling splash particles when the boat/ship interacts with the ocean.

@erikdubbelboer
Copy link
Author

@script526 of course, everyone is free to use it. Cool looking project, and especially nice that it's open source!

@script526
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment