创建:
首先,肯定需要一个C++类(Actor就可以)(我们就叫他Projectile--弹)
然后创建基于Projectile的蓝图类
一个炮弹需要什么:作为炮弹的物体、射出去的粒子效果、爆炸之后的粒子效果等等
h:
#include "Components/StaticMeshComponent.h" //炮弹
#include "Particles/ParticleSystemComponent.h" //粒子效果
#include "GameFramework/ProjectileMovementComponent.h" //用于制作子弹炮弹的抛物线
UProjectileMovementComponent *ProjectileMovementComponent = nullptr;
UPROPERTY(VisibleAnywhere,Category="Components")
UStaticMeshComponent* CollisionMesh = nullptr;
UPROPERTY(VisibleAnywhere, Category = "Components")
UParticleSystemComponent* LaunchParticle = nullptr; //烟雾 火
UPROPERTY(VisibleAnywhere, Category = "Components")
UParticleSystemComponent* ImpactParticle = nullptr; //撞击
void LaunchProjectile(float Speed); //调用此函数时 设置速度 顺便让抛物线组件启用
UFUNCTION() //撞击事件
void OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit);
cpp:
AProjectile::AProjectile()
{
// 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;
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(FName("ProjectileMovement")); //生成组件
ProjectileMovementComponent->bAutoActivate = false; //自动飞行调成false
//炮弹
CollisionMesh = CreateDefaultSubobject<UStaticMeshComponent>(FName("CollisionMesh")); //创建CollisionMesh
SetRootComponent(CollisionMesh);//设置成根结点
CollisionMesh->SetNotifyRigidBodyCollision(true); //设置可以撞击到物体
CollisionMesh->SetVisibility(true); //设置可见
LaunchParticle = CreateDefaultSubobject<UParticleSystemComponent>(FName("LaunchParticle"));
LaunchParticle->AttachTo(RootComponent);//将粒子效果绑定在根结点上(即CollisionMesh)
LaunchParticle->SetAutoActivate(true); //不要创建好就启动
ImpactParticle = CreateDefaultSubobject<UParticleSystemComponent>(FName("ImpactParticle"));
ImpactParticle->AttachTo(RootComponent);
ImpactParticle->SetAutoActivate(false); //不要创建好就启动
}
// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{
Super::BeginPlay();
CollisionMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit); //将Projectile绑定在了物件上
}
// Called every frame
void AProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AProjectile::LaunchProjectile(float Speed) { //此函数用于鼠标左键输入连着的Fire函数(详情请见之前的生成子弹文章)
ProjectileMovementComponent->SetVelocityInLocalSpace(FVector::ForwardVector*Speed); //设置速度,因为是矢量所以乘向前的向量
ProjectileMovementComponent->Activate(); //可以飞行了
}
//碰撞后发生的事件
void AProjectile::OnHit(UPrimitiveComponent* HitComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
UE_LOG(LogTemp, Warning, TEXT("Hit")); //撞击后给个提示
ImpactParticle->Activate(true); //撞击后产生撞击后的粒子效果
CollisionMesh->SetNotifyRigidBodyCollision(false); //碰撞之后再也不发生碰撞事件
SetRootComponent(ImpactParticle);//删除了作为根结点的炮弹,所以要在删除前换一个根结点
CollisionMesh->DestroyComponent(); //不是DestroyActor,Component是单一一个
}
之后在Projectile的蓝图中就可以看到
如果还有一个DefaultSceneRoot,只需保存重启之后便会消失
作用力:
在原有的Projectile的代码中添加
h:
#include "PhysicsEngine/RadialForceComponent.h"
UPROPERTY(VisibleAnywhere, Category = "Components")
URadialForceComponent* ExplosionForce = nullptr;
cpp:
在AProjectile中写:
ExplosionForce= CreateDefaultSubobject<URadialForceComponent>(FName("ExplosionForce"));
ExplosionForce->AttachTo(RootComponent);
ExplosionForce->SetAutoActivate(false);
在OnHit中写:
ExplosionForce->FireImpulse(); //撞击后便释放力
编译后在蓝图中可见: