UE4之自定义粒子系统模块

       粒子模块用于设置粒子的各种属性,如颜色和速度等。

UE4之自定义粒子系统模块_第1张图片

       粒子模块基类为UParticleModule,所有的粒子模块都是继承自这个基类,它有两个虚函数Spawn和Update,我们一般重载这两个函数即可。

virtual void   Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime, FBaseParticle* ParticleBase);
virtual void   Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime);

        粒子模块一般会继承两级,第一级用于分类,第二级用于具体的实现,如UParticleModuleColorBase为第一级,在右键菜单中显示为“Color”一级菜单,UParticleModuleColorOverLife继承自UParticleModuleColorBase为第二级,在右键菜单中显示为Color下的二级菜单“Color Over Life”。
UE4之自定义粒子系统模块_第2张图片

       在这个例子中实现UParticleModuleCustomBase和UParticleModuleCustomShape两级,UParticleModuleCustomShape通过设定粒子的初始速度实现一个自定义的形状。在右键菜单中分别显示为一级“Custom”和二级“Shape”

UCLASS(editinlinenew, hidecategories=Object, abstract, meta=(DisplayName = "Custom"))
class UParticleModuleCustomBase : public UParticleModule
{
	GENERATED_UCLASS_BODY()
};
UCLASS(editinlinenew, collapsecategories, hidecategories = Object, meta = (DisplayName = "Shape"))
class UParticleModuleCustomShape : public UParticleModuleCustomBase
{
	GENERATED_UCLASS_BODY()
	
public:
	virtual void   Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime, FBaseParticle* ParticleBase);
	virtual void   Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime);
};

        以下为实现部分的主要代码:

#define COS(degree) (FMath::Cos(FMath::DegreesToRadians(degree)))
#define SIN(degree) (FMath::Sin(FMath::DegreesToRadians(degree)))

UParticleModuleCustomShape::UParticleModuleCustomShape(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	//同时需要Spawn和Update两个函数
	bSpawnModule = true;
	bUpdateModule = true;
}


void UParticleModuleCustomShape::Spawn(FParticleEmitterInstance* Owner, int32 Offset, float SpawnTime, FBaseParticle* ParticleBase)
{
	SPAWN_INIT;
	{
		float p = 3.0 / 2;
		int32 degree = FMath::RandRange(0, 360 * 4);//在周期内随机获取一个角度
		//以下为花瓣曲线方程,可以换成其他的方程,生成不同的形状,其中p为参数可以控制花瓣数和周期
		float y = SIN(p * degree) * COS(degree);
		float z = SIN(p * degree) * SIN(degree);
		Particle.Velocity = 100 * FVector(0, y, z);//在yz平面生成,并将形状扩大100倍
		Particle.BaseVelocity = Particle.Velocity;
	}
}

void UParticleModuleCustomShape::Update(FParticleEmitterInstance* Owner, int32 Offset, float DeltaTime)
{
	BEGIN_UPDATE_LOOP;
	{
		Particle.Velocity *= (1 - Particle.RelativeTime * Particle.RelativeTime);//速度随时间衰减
	}
	END_UPDATE_LOOP;
}

       在Spawn函数中有一个宏SPAWN_INIT,将其展开之后的代码是:

check((Owner != NULL) && (Owner->Component != NULL));
const int32		ActiveParticles	= Owner->ActiveParticles;
const uint32		ParticleStride	= Owner->ParticleStride;
uint32			CurrentOffset	= Offset;
FBaseParticle&	Particle		= *(ParticleBase);

        同样展开BEGIN_UPDATE_LOOP和END_UPDATE_LOOP,是一个循环:

{
	check((Owner != NULL) && (Owner->Component != NULL));
	int32&			ActiveParticles = Owner->ActiveParticles;
	uint32			CurrentOffset	= Offset;
	const uint8*		ParticleData	= Owner->ParticleData;
	const uint32		ParticleStride	= Owner->ParticleStride;
	uint16*			ParticleIndices	= Owner->ParticleIndices;
	for(int32 i=ActiveParticles-1; i>=0; i--)
	{
		const int32	CurrentIndex	= ParticleIndices[i];
		const uint8* ParticleBase	= ParticleData + CurrentIndex * ParticleStride;
		FBaseParticle& Particle		= *((FBaseParticle*) ParticleBase);	
		if ((Particle.Flags & STATE_Particle_Freeze) == 0)
		{
			//自己的代码
		}
		CurrentOffset				= Offset;
	}
}

  

       在Spawn中随机取得花瓣曲线上一个点,将其作为该粒子的速度,只要粒子数够多就可以均匀分布在曲线上,形成一个花瓣曲线。在Update中让粒子速度以相对时间的平方衰减,并在粒子消失之时变成静止。

       这两个类定义好之后,打开编辑器,定义一个粒子系统,并在一个粒子实例上右键添加Custom下的Shape模块,并设置好相关的参数(最好将Spawn模块中的Rate设置为0,Burst下的Burst List中的Count设置为需要生成的粒子数,这样粒子就是一次性生成,而不是连续生成),这时粒子会形成花瓣曲线的形式(注:由于粒子系统的计算方式是以模块从上到下的方式,所以在Shape模块后面不能再有改变粒子速度的模块,如InitVelocity)。

UE4之自定义粒子系统模块_第3张图片

UE4之自定义粒子系统模块_第4张图片

        利用该模块可以制作自定义形状的烟花类型,将“内容示例”中的烟花粒子修改并添加该模块后制作出如下各种形状的烟花:

UE4之自定义粒子系统模块_第5张图片
 

UE4之自定义粒子系统模块_第6张图片

UE4之自定义粒子系统模块_第7张图片

 

你可能感兴趣的:(Unreal,Engine,UE4,粒子系统,粒子模块)