Unreal Engine: Cascade Extender

A plugin written in C++ for Unreal Engine. This plugin adds in it currents state 3 new location modules, namely: Box, Box (seeded) and Fixed Offset. And 2 new beam modules: Source (Screen Space) and Target (Screen Space).


The Box modules allow users to easily emit particles from the vertices, edges, faces or volume of a box given by the provided dimensions. It is also capable of giving the particles a start velocity, normalized or unnormalized, based on it's position in the volume or the face normal, and multiplied by the velocity scaler distribution. By setting one of the dimensions to zero and using edge mode you can easily make 2D squares, see first video below. Two distribution vectors are also provided for the applying a translation and/or a rotation.

The Fixed Offset module allows the user to spawn particles in a given direction with an offset between them. The user needs to provide the number of points controlled by a float distribution over emitter time. And the offset between each particle controlled by two float distributions. The algorithm samples the "Element Offset" distribution with the current element index, and multiplies this value with the "Offset Scaler" distribution which is sampled with the emitter time. The spawning goes sequentially over the points and restarts when it reached the cap value provided by the user. This module also provides two distribution vectors for applying translation and rotation, and a distribution vector for the generated line. It also has an option for making the particles recalculate its position each frame, like the built-in socket module provides, see the second video below.

The two Beam modules are a Target and Source module for creating beams with their endpoints defined in screen space, utilizing Normalized Device Coordinates or using an offset in pixels from the edge, of the viewport of the player. These modules did require a small change in the engine, due to the two base classes (UParticleModuleBeamSource and UParticleModuleBeamTarget) not being declared with ENGINE_API and containing MinimalApi in the UCLASS attribute. Deriving from these classes was necessary due to the emitter instance class relying on them. Also deriving from them added some properties to the properties panel of the modules which were not necessary for the screen space logic. For hiding them I registered two IDetailCustomization derived classes, which allows you to fully customize the panels. For each module I changed the text and tooltip of a boolean property so I didn't need to add a new variable, but could reuse an existing variable. And hid two unused variables.

#include "SourceModuleCustomization.h"
#include "DetailLayoutBuilder.h"
#include "Particles/Beam/ParticleModuleBeamSource.h"

TSharedRef FSourceModuleCustomization::MakeInstance()
{
	return MakeShareable(new FSourceModuleCustomization);
}

void FSourceModuleCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder)
{
	DetailBuilder.HideProperty("SourceName", UParticleModuleBeamSource::StaticClass());
	DetailBuilder.HideProperty("SourceMethod", UParticleModuleBeamSource::StaticClass());

	TSharedRef propHandle = DetailBuilder.GetProperty("bSourceAbsolute", UParticleModuleBeamSource::StaticClass());
	propHandle->SetPropertyDisplayName(FText::FromString("Use edge offset"));
	propHandle->SetToolTipText(FText::FromString("Use edge offset in pixels instead of NDC\n>= 0 offset from left | < 0 offset from right"));
}
void FCascadeModuleCustomizationsModule::StartupModule()
{
	FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked("PropertyEditor");

	//Custom detail views
	PropertyModule.RegisterCustomClassLayout("ModuleBeamSourceScreen", 
		FOnGetDetailCustomizationInstance::CreateStatic(&FSourceModuleCustomization::MakeInstance));
	PropertyModule.RegisterCustomClassLayout("ModuleBeamTargetScreen",
		FOnGetDetailCustomizationInstance::CreateStatic(&FTargetModuleCustomization::MakeInstance));
}