Stanford UE4 & UE5 C++ 开发 课程笔记(二) 实现粒子发射效果

实现粒子类

1. 创建C++父类

在编辑器中创建新的C++类LMagicProjectile(继承Actor)

在这里插入图片描述

2. 添加魔法弹

在头文件中添加如下组件:

class ROGUELIKEACTION_API ALMagicProjectile : public AActor
{
    
    
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ALMagicProjectile();

protected:

	// 魔法弹的模型
	UPROPERTY(VisibleAnywhere)
	USphereComponent * SphereComponent;
	// 投掷体运动系统
	UPROPERTY(VisibleAnywhere)
	UProjectileMovementComponent * ProjectileMovementComponent;
	// 粒子系统
	UPROPERTY(VisibleAnywhere)
	UParticleSystemComponent * EffectComponent;
	
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;
};

在.cpp文件的构造函数中添加初始化的代码:

ALMagicProjectile::ALMagicProjectile()
{
    
    
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	SphereComponent = CreateDefaultSubobject<USphereComponent>("SphereComponent");
	// 根据名称指定自定义的碰撞通道设置,随后会在编辑器中定义
	SphereComponent->SetCollisionProfileName("Projectile");
	RootComponent = SphereComponent;
	
	ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>("ProjectileMovementComponent");
	// 运动初速度
	ProjectileMovementComponent->InitialSpeed = 1000.0f;
	// 球体每帧都会旋转以适应当前运动的方向
	ProjectileMovementComponent->bRotationFollowsVelocity = true;
	// 使用局部坐标系定义
	ProjectileMovementComponent->bInitialVelocityInLocalSpace = true;

	// 粒子系统
	EffectComponent = CreateDefaultSubobject<UParticleSystemComponent>("EffectComponent");
	EffectComponent->SetupAttachment(SphereComponent);

}

3. 蓝图类设置

跟上一节中的Character一样,从C++类中派生出新的蓝图类MagicProjectileBP

在这里插入图片描述
打开蓝图类,在粒子系统组件中选择在上一节中下载好的P_Gideon_Primary_Projectile模板

在这里插入图片描述

实现发射效果

1. 在Character类中添加新组件

首先,在Character类中添加两个新组件

protected:

	// 魔法攻击发射的子弹类型,C++只负责定义,之后在继承的蓝图类中指定具体是哪种子弹
	UPROPERTY(EditAnywhere, Category="Attack")
	TSubclassOf<AActor> ProjectileClass;

	// 发动攻击时的人物动画,也是蓝图中具体指定
	UPROPERTY(EditAnywhere, Category="Attack")
	UAnimMontage * AttackAnim;

2. 在角色蓝图类中指定具体类型

打开角色蓝图,将ProjectClass指定为MagicProjectileBP,AttackAnim指定为Primary_Attack_A_Medium_Montage

请添加图片描述

3. 实现攻击触发的逻辑

首先,实现执行攻击动画与生成魔法弹的PrimaryAttack函数:

void ALCharacter::PrimaryAttack()
{
    
    
	// 执行攻击动画
	PlayAnimMontage(AttackAnim);
	// 获取人物模型中手的坐标,GetSocketLocation可以获取骨骼中的插件
	const FVector HandLocation = GetMesh()->GetSocketLocation("Muzzle_01");
	const FTransform SpawnTM = FTransform(GetControlRotation(), HandLocation);
	FActorSpawnParameters SpawnParams;
	// 无论任何情况都生成(无视重叠,碰撞,覆盖...)
	SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
	// 将角色自身作为触发者传入,以便子弹判断正确的交互对象
	SpawnParams.Instigator = this;
	// 在世界中生成
	GetWorld()->SpawnActor<AActor>(ProjectileClass, SpawnTM, SpawnParams);
}

但是,我们希望最终的效果是人物完成攻击动作后才会发射子弹,而上述代码会造成人物动作刚开始执行,子弹就飞了出去,所以一个暂定的办法是设置一个定时器,让子弹生成操作延时触发
Character.h

protected:
	// 头文件中添加新属性
	FTimerHandle TimerHandle_PrimaryAttack;

Character.cpp

void ALCharacter::PrimaryAttack()
{
    
    
	// 先执行攻击动画
	PlayAnimMontage(AttackAnim);
	// 延时触发生成,延时器绑定需要触发的函数
	GetWorldTimerManager().SetTimer(TimerHandle_PrimaryAttack, this, &ALCharacter::PrimaryAttack_TimeElapsed, 0.2f);
}

// 函数名和SetTimer中的对应
void ALCharacter::PrimaryAttack_TimeElapsed()
{
    
    
	// 生成角度和坐标
	// 获取人物模型中手的坐标,GetSocketLocation可以获取骨骼中的插件
	const FVector HandLocation = GetMesh()->GetSocketLocation("Muzzle_01");
	const FTransform SpawnTM = FTransform(GetControlRotation(), HandLocation);
	FActorSpawnParameters SpawnParams;
	// 无论任何情况都生成(无视重叠,碰撞,覆盖...)
	SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
	// 将角色自身作为触发者传入,以便子弹判断正确的交互对象(不要和自身交互)
	SpawnParams.Instigator = this;
	// 在世界中生成对应子弹类型
	GetWorld()->SpawnActor<AActor>(ProjectileClass, SpawnTM, SpawnParams);
}

4. 绑定鼠标左键为攻击键

在PlayerCharacter.cpp文件的SetupPlayerInputComponent绑定新的Action:

// 射击
PlayerInputComponent->BindAction("PrimaryAttack", IE_Pressed, this, &ALCharacter::PrimaryAttack);

在项目设置中进行操作映射:

在这里插入图片描述

最终效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45943887/article/details/127620416