動作/射擊游戲中,擊中角色時常常伴隨着血花效果,增強打擊感的同時,也方便了玩家對命中與否的判斷。
血液效果分兩塊,首先是受傷部位在受擊瞬間產生血霧粒子,然后在身體、地面、牆面等處附加血跡貼圖。
本文討論的是第一塊。
先在項目文件夾右鍵新建一個particlesystem,默認是長這樣的:
可以看到是一坨紅綠藍的東西裊裊升起。
這坨東西其實就是由一個個尖尖的小粒子,通過一系列運動規律展現出來的,每個單元的外觀由required→emitter中的材質決定
於是我們要把材質替換為血霧的基本單元。
因此我們要先制作一個M_Blood1材質。
通過百度圖片搜索“血”,我挑選出了一張比較合適的圖片作為貼圖
通過ps中反相一系列處理得到了大致的alpha貼圖
(由於我不是美工,效果有限還請見諒)
接下來就是材質連線了,只實現了基本的貼圖顯示
blend mode選擇translucent,兩張貼圖分別連到對應位置即可
然后將該材質設為粒子發射的材質
為了方便觀察我們把它拖到場景中
依稀有點血霧的樣子了,不過炊煙裊裊升起肯定不對
於是我們需要調整initial velocity
我是這么設置的
向自身x軸方向恆定速度噴出,並且有個向上的初速度
然后還會有向下的加速度(右鍵添加const acceleration)
加速度過大過小都不好,我設為-200
然后我修改了required→duration中的發射持續時間以及循環數(1表示不循環只噴一輪duration)
當然spawn中的發射速度也可以自行調整
下面就是如何在角色受擊時顯示粒子特效的問題了,倘若直接使用anim notify,無法讓粒子恰好處於受擊位置(傷口處),因此我們新建一個C++類MyParticleActor
MyParticleActor.h文件
#pragma once #include "GameFramework/Actor.h" #include "MyParticleActor.generated.h" UCLASS() class SANSHAOYESWORD_API AMyParticleActor : public AActor { GENERATED_BODY() public: // Sets default values for this actor's properties AMyParticleActor(); protected: // Called when the game starts or when spawned virtual void BeginPlay() override; UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = MyParticle, meta = (AllowPrivateAccess = "true")) UParticleSystemComponent* particle = NULL; public: // Called every frame virtual void Tick(float DeltaTime) override; };
MyParticleActor.cpp在構造函數中創建particle組件
AMyParticleActor::AMyParticleActor() { // 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; particle=CreateDefaultSubobject<UParticleSystemComponent>(TEXT("particle")); particle->SetupAttachment(RootComponent); }
然后進入編輯器,創建繼承MyParticleActor的藍圖bp_blood1
將template設為我們剛才制作的血霧粒子即可
還需要對這個actor的life span進行設置,我設置的是1.5秒
最后我們進入receivedamage函數,也就是處理角色受擊的代碼,插入下列生成血霧粒子代碼
//扣完血馬上進行流血效果 if (particleactor_blood) { FActorSpawnParameters SpawnParams; AMyParticleActor* newblood_particleactor = GetWorld()->SpawnActor<AMyParticleActor>( particleactor_blood, hitlocation,//產生於受擊位置 vct2sp((attacker->GetActorLocation()-hitlocation)).Rotation() //hitlocation和attacker的中心連線的水平分量作為particle發射方向 , SpawnParams);// newblood_particleactor->AttachRootComponentTo(GetMesh(),FName(*hitbonename), EAttachLocation::KeepWorldPosition,true);// } else { throw std::exception("流血粒子物體缺失!!!!"); }
當然在此之前要讓Character類暴露給藍圖一個particleactor_blood
//用於受擊時流血效果的 UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = MyParticle, meta = (AllowPrivateAccess = "true")) UClass* particleactor_blood = NULL;
最后在Character藍圖中將particleactor_blood設為我們剛才制作好的bp_blood1就大功告成了
大致效果(截圖看的不太明顯其實明顯有噴出來的動態過程):