粒子模块技术指南

添加新粒子模块以自定义粒子系统行为的程序员指南。

Windows
MacOS
Linux

虚幻编辑器4(UE4)的粒子系统可包含任意数量的粒子发射器,每个粒子发射器都包含会影响其粒子行为的模块。使用自定义模块和发射器类型扩展该系统的过程非常简单,本文档中包含示例,以说明如何实现此目的。

ParticleModule基类

所有粒子模块都派生自相同的基类——ParticleModule(在UE4/Engine/Source/Runtime/Engine/Classes/Particles/Modules/ParticleModule.h中定义)。

成员变量

`ParticleModule`类包含下列成员变量:

变量

概述

bSpawnModule

布尔,指示模块是否要求生成的粒子通过它输送(即,Spawn()/SpawnEditor()函数发挥作用)。默认值为`false`。

bUpdateModule

布尔,指示模块是否要求更新的粒子通过它输送(即,Update()/UpdateEditor()函数发挥作用)。默认值为`false`。

bCurvesAsColor

布尔,指示模块中的Distribution(曲线)属性是否包含颜色数据。当它为`true 时,在曲线编辑器中绘制的曲线将显示其当前颜色,而非指定的`ModuleEditorColor。默认值为`false`。

b3DDrawMode

布尔,指示模块应渲染其3D可视化辅助。默认值为`false`。

bSupported3DDrawMode

布尔,指示模块支持渲染3D可视化帮助程序(即`Render3DPreview()函数发挥作用)。默认值为`false

bEnabled

布尔,指示是否启用模块。默认值为`true`。

bEditable

布尔,指示设计师已启用此模块。在LOD级别中使用,用以确定细节级别较低的LOD级别是否已被修改。默认值为`true`。

ModuleEditorColor

与模块关联的颜色。在曲线编辑器中绘制的来自此模块的曲线将以此颜色显示。

启用`bCurvesAsColor`时,曲线将以它们表示的实际颜色值绘制。

在此类中,也会定义一个`ModuleType`列举。此类型指示哪些类型的发射器可以使用此模块。下表对可用的类型进行了说明:

类型(EPMT)

说明

General

可被所有发射器类型使用的通用模块。

TypeData

此模块是TypeData模块——规定被实例化的发射器类。

Beam

此模块仅可被光束发射器使用。

Trail

此模块仅可被轨迹发射器使用。

成员函数

`ParticleModule`类包含多个虚拟成员函数,它们可在你编写自己的模块时提供兴趣点。(此类还包含众多其他成员函数,但是它们与自定义模块主题无关,因此我们在本指南中不对它们进行说明。)这些函数包括:

函数

概述

void Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime)

在发射器新生成的粒子上调用。在此处,模块可以在每个粒子被创建时设置/修改它们的初始值。

void Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime)

在被粒子发射器更新的粒子上调用。在此处,模块可以对被更新的粒子执行运算,例如,更新其颜色或速度。

uint32 RequiredBytes(UParticleModuleTypeDataBase* TypeData)

返回模块要求粒子负载块中具有的字节数。这使模块能够按粒子存储一些它需要的数据。

uint32 RequiredBytesPerInstance()

返回模块要求发射器 按实例 数据块中具有的字节数。这使模块能够按发射器实例存储一些它需要的数据。

virtual void CompileModule( struct FParticleEmitterBuildInfo& EmitterInfo )

必须为可与GPU粒子发射器配合使用的模块实现`CompileModule()`。要将此模块的效果应用给模拟,此模块应修改发射器信息结构体。

创建自定义模块

编写自定义模块仅涉及到覆盖上述函数以实现所需的效果。例如,实现的模块将粒子颜色设置为底色乘以按照即将创建的Distribution生成的系数增减后的速度。

模块的基类定义它在级联的 右键单击 模块菜单中的标题。因此,在我们的示例中,我们需要从`ParticleModuleColorBase`类派生,以确保该模块在 颜色(Color) 子菜单中显示。

模块声明

UCLASS(editinlinenew,collapsecategories,hidecategories=Object)
public class UParticleModuleColorByVelocity : public UParticleModuleColorBase
{
    /**

     *   此为在将它设置为颜色前
     *   用以对每个相应的速度元素进行增减的数值。检索该数值的方法是使用 
     *   Particle.RelativeTime。
     *
     *   例如,如果ScaleVelocity 是(0.25,0.5,1.0),速度
     *   是(2.0,2.0,0.0),那么粒子颜色将被设置为(0.5,1.0,0.0);
     */

    var(Color)   rawdistributionvector   ScaleVelocity;

    cpptext
    {
       virtual void   Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime);
       virtual void   Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime);
    }
}

注意事项:

  1. 此模块被标记为在生成和更新阶段都对粒子执行运算(bSpawnModule`和`bUpdateModule`都设置为`true)。

  2. 我们的模块不需要按粒子或按实例数据,因此我们未覆盖 RequiredBytes*() 函数。

此示例要求在发射器模块堆栈中,发射器具有的 InitialColor 模块先于 ColorByVelocity 模块。 它还要求粒子发射器使用一个采用 VertexColor 表达式的材质,以显示被操纵的粒子颜色。

模块实现

构造函数创建指定给`ScaleVelocity`的`DistributionVectorConstant`并告知引擎它应处理粒子生成和更新。

UParticleModuleColorByVelocity::UParticleModuleColorByVelocity(const FObjectInitializer& ObjectInitializer)
:Super(ObjectInitializer)
{
    bSpawnModule = true;
    bUpdateModule = true;

    UDistributionVectorConstant* DistributionScaleVelocity = ConstructorHelpers::CreateDefaultSubobject<UDistributionVectorConstant>(this, TEXT("DistributionScaleVelocity"));
    DistributionScaleVelocity->Constant = FVector(1.0f, 1.0f, 1.0f);
    ScaleVelocity.Distribution = DistributionScaleVelocity;
}

Spawn() 函数中,代码将设置它对粒子的所有初始影响。并非每个模块都需要`Spawn()`调用,但此模块确实需要。

void UParticleModuleColorByVelocity::Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime)
{
   SPAWN_INIT;
   {
      FVector ColorScale    = ScaleVelocity.GetValue(Particle.RelativeTime, Owner->Component);
      Particle.Color        = FLinearColor(
                                            Particle.BaseColor.R * Particle.Velocity.X * ColorScale.X,
                                            Particle.BaseColor.G * Particle.Velocity.Y * ColorScale.Y,
                                            Particle.BaseColor.B * Particle.Velocity.Z * ColorScale.Z);
   }
}

Spawn()函数使用`Particle.RelativeTime`从Distribution检索`ScaleVelocity`数值。此数值乘以速度即可得到增减后的速度数值。然后,`Particle.Color`被设置为`BaseColor`乘以增减速度计算的结果。

SPAWN_INIT`是一个宏,它设置引用生成的粒子的`FBaseParticle,以及访问粒子数据时经常使用的一些其他数值,例如到粒子负载的偏移轨迹等。有关完整细节,请参阅//depot/UE4/Engine/Source/Runtime/Engine/Public/ParticleHelper.h

此为它直接在其中设置`Particle.Color`的破坏模块。在它之前创建任何仅修改`Particle.Color`的模块都是无意义的。但是,如果它还修改`BaseColor`,例如 **InitialColor** 模块,那么它仍然会发挥作用。

此特定模块中的 Update() 函数几乎与 Spawn() 完全相同。差异在于,每个活动粒子都在单个循环中被更新。

void UParticleModuleColorByVelocity::Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime)
{
   BEGIN_UPDATE_LOOP;
   {
      FVector ColorScale    = ScaleVelocity.GetValue(Particle.RelativeTime, Owner->Component);
      Particle.Color        = FLinearColor(
                                             Particle.BaseColor.R * Particle.Velocity.X * ColorScale.X,
                                             Particle.BaseColor.G * Particle.Velocity.Y * ColorScale.Y,
                                             Particle.BaseColor.B * Particle.Velocity.Z * ColorScale.Z);
   }
   END_UPDATE_LOOP;
}

BEGIN_UPDATE_LOOP/`END_UPDATE_LOOP`是宏,它们设置循环遍历所有活动粒子的代码块并在每个粒子上执行它们之间包含的代码。请参阅`UnParticleHelper.h`了解完整细节。

以下屏幕截图展示了作用中的 ColorByVelocity 模块。粒子的 InitialVelocity 随机设置为 [(0,0,0),(200,200,0)]。每个粒子的 InitialColor 都设置为白色。ColorByVelocity 的 VelocityScale 数值设置为常量 (0.005, 0.005, 0)。因此,每个粒子的颜色都设置为:

Velocity * VelocityScale

ColorByVelocity.JPG

Tags
Select Skin
Light
Dark

Welcome to the new Unreal Engine 4 Documentation site!

We're working on lots of new features including a feedback system so you can tell us how we are doing. It's not quite ready for use in the wild yet, so head over to the Documentation Feedback forum to tell us about this page or call out any issues you are encountering in the meantime.

We'll be sure to let you know when the new system is up and running.

Post Feedback