UE Reflection Specifier
BlueprintNativeEvent - 在C++中实现基础,能够被蓝图扩展
BlueprintCallable - 允许子类触发
Tips
C++ const函数可以将函数变成无执行流的蓝图函数
使用PostInitializeComponents中实现代理绑定更好
Audio
Sound Cue
节点
Wave Player - 播放Sound Wave
Random - 随机选择Sound Wave并输出
Modulator - 随机调整音频pitch和volume
Doppler - 多普勒效应
其他
Attenuation Setting - 配置音频的Attenuation
Animation Blueprint
Event Graph
基于事件的图表,用于每帧更新ABP和计算AnimGraph中的值
Animation Graph
用于采样、混合和操控Pose的图表,并输出最终姿势
Save Pose - 缓存该Pose
Use Cached Pose - 使用Pose
Blend Poses by bool - 使用布尔值控制输出Pose
项目代码
Github: https://github.com/yufeige4/ActionRoguelike
Tips:UE4必须在build文件中加入"XAudio2_9"模块才能使用AudioComponent
实现火球飞行和击中音效 - Assignment 3
实现角色死亡动画逻辑
角色死亡基础逻辑
实现施法特效 (动画通知) + 火球拖尾 (SpawnEmitterAttached) + 爆炸时相机抖动 - Assignment 3
实现角色受伤闪烁 - Assignment 3
实现伤害字体显示 + 动画 - Assignment 3
统一交互刷新物体基类
交互刷新治疗药水 + 音效 + 特效 - Assignment 3
Note: UE4 C++ Interface继承时需继承的时I开头的Interface而不是U开头的Interface !!!
// GProjectileBase.h
// ...
protected:
// 飞行音效
UPROPERTY(VisibleAnywhere, Category = "Components")
UAudioComponent* AudioComp;
public:
virtual void BeginPlay() override;
// GProjectileBase.cpp
// ...
void AGProjectileBase::BeginPlay()
{
Super::BeginPlay();
AudioComp->Play();
}
// GMagicProjectile.h
// ...
UPROPERTY(EditDefaultsOnly, Category = "Basic")
float TimeToSelfDestroy;
UPROPERTY(EditDefaultsOnly, Category = "Audio")
USoundCue* ImpactSound;
UPROPERTY(EditDefaultsOnly, Category = "Effects")
TSubclassOf<UCameraShakeBase> ImpactShake;
FTimerHandle TimerHandle_selfDestroy;
void SelfDestroy();
virtual void Explode_Implementation() override;
// GMagicProjectile.cpp
// ...
void AGMagicProjectile::BeginPlay()
{
Super::BeginPlay();
GetWorldTimerManager().SetTimer(TimerHandle_selfDestroy,this,&AGMagicProjectile::SelfDestroy,TimeToSelfDestroy);
}
void AGMagicProjectile::SelfDestroy()
{
GetWorldTimerManager().ClearTimer(TimerHandle_selfDestroy);
if(GEngine)
{
GEngine->AddOnScreenDebugMessage(0, 2, FColor::Black, TEXT("SelfDestroyed!"));
}
Destroy();
}
void AGMagicProjectile::Explode_Implementation()
{
GetWorldTimerManager().ClearTimer(TimerHandle_selfDestroy);
UGameplayStatics::PlaySoundAtLocation(GetWorld(),ImpactSound,GetActorLocation(),GetActorRotation());
// 爆炸相机抖动
UGameplayStatics::PlayWorldCameraShake(GetWorld(),ImpactShake,GetActorLocation(),0.0f,2500.0f);
Super::Explode_Implementation();
}
// GAttributeComponent.h
// ...
protected:
// 最大生命值
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Attributes")
float MaxHealth;
public:
UFUNCTION(BlueprintCallable)
bool IsAlive() const;
// GAttributeComponent.cpp
// ...
UGAttributeComponent::UGAttributeComponent()
{
CurrHealth = 100.0f;
MaxHealth = 100.0f;
}
bool UGAttributeComponent::ApplyHealthChange(float Delta)
{
CurrHealth = FMath::Clamp(CurrHealth+Delta,0.0f,MaxHealth);
// 调用代理
OnHealthChanged.Broadcast(nullptr,this,CurrHealth,Delta);
return true;
}
bool UGAttributeComponent::IsAlive() const
{
return Health > 0.0f;
}
// GCharacter.h
// ...
protected:
void DamagedFlash();
UFUNCTION()
void OnHealthChanged(AActor* InstigatorActor, UGAttributeComponent* OwningComp, float NewHealth, float Delta);
// GCharacter.cpp
// ...
void AGCharacter::OnHealthChanged(AActor* InstigatorActor, UGAttributeComponent* OwningComp, float NewHealth, float Delta)
{
if(Delta<0.0f)
{
DamagedFlash();
}
if(NewHealth<=0.0f && Delta<0.0f)
{
APlayerController* PC = Cast<APlayerController>(GetController());
DisableInput(PC);
}
}
其余代码见Github。