UEC++学习(三)之 角色死亡,切换旁观者类,高处掉血Landed等

目录

通过委托实现角色死亡

角色死亡后切换到旁观者类

角色从高处掉落扣血


通过委托实现角色死亡

使用的是非动态多播

声明两个仅供C++使用的委托:委托要用F开头

//用于广播角色死亡
DECLARE_MULTICAST_DELEGATE(FOnDeath)
//用于广播角色血量
DECLARE_MULTICAST_DELEGATE_OneParam(FOnHealthChange,float)

创建这两个委托变量

	//创建委托变量
	FOnDeath OnDeath;
	FOnHealthChange OnHealthChange;

在血量减少时执行委托:Broadcast()


void USTUHealthComponent::OnTakeAnyDamageComponent(AActor* DamagedActor, float Damage, const UDamageType* DamageType, AController* InstigatedBy, AActor* DamageCauser)
{
	if (Damage <= 0.0f || IsDead())
		return;
	Health = FMath::Clamp(Health - Damage, 0.0f, MaxHealth);


	OnHealthChange.Broadcast(Health);
	if (IsDead())
	{
		//执行委托,通知所有订阅这个委托的类
		OnDeath.Broadcast();
	}
}

在角色类中订阅绑定这两个委托

void ASTUBaseCharacter::BeginPlay()
{
	Super::BeginPlay();
	check(HealthComponent);
	check(HealthTextComponent);
	check(GetCharacterMovement());
	
	OnHealthChange(HealthComponent->GetHealth());

	//订阅委托 动态多播用AddDynamic 非动态多播用AddUObject
	HealthComponent->OnDeath.AddUObject(this, &ASTUBaseCharacter::OnDeath);
	HealthComponent->OnHealthChange.AddUObject(this, &ASTUBaseCharacter::OnHealthChange);
}


void ASTUBaseCharacter::OnDeath()
{
	UE_LOG(BaseCharacterLog, Display, TEXT("Player %s is dead"), *GetName());

	PlayAnimMontage(DeathAnimMotage);
	//关闭移动
	GetCharacterMovement()->DisableMovement();
	//五秒后销毁
	SetLifeSpan(5.0f);
}

void ASTUBaseCharacter::OnHealthChange(float Health)
{
	HealthTextComponent->SetText(FText::FromString(FString::Printf(TEXT("Hp %.0f"), Health)));
}

创建蒙太奇动画:UAnimMontage

	UPROPERTY(EditDefaultsOnly, Category = "Animation")
		UAnimMontage* DeathAnimMotage;

播放蒙太奇:PlayAnimMontage()

	PlayAnimMontage(DeathAnimMotage);

关闭蒙太奇的自动混出,不然播放结束后会回到初始状态

角色死亡后切换到旁观者类

Controller->ChangeState():切换到旁观者 NAME_Spectating,NAME_Playing

GetCapsuleComponent()->SetCollisionResponseToAllChannels():设置碰撞体类型

	#include "GameFramework/Controller.h"


void ASTUBaseCharacter::OnDeath()
{
	UE_LOG(BaseCharacterLog, Display, TEXT("Player %s is dead"), *GetName());

	PlayAnimMontage(DeathAnimMotage);
	//关闭移动
	GetCharacterMovement()->DisableMovement();
	//五秒后销毁
	SetLifeSpan(LifeSpanOnDeath);

    //切换到旁观者类
	if (Controller)
	{
		Controller->ChangeState(NAME_Spectating);
	}
    //关闭胶囊体碰撞
	GetCapsuleComponent()->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Ignore);
}

角色从高处掉落扣血

要使用到Character中的Landed,这里可以选择重载Landed函数或者使用LandedDelegate委托

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLandedSignature, const FHitResult&, Hit);

选择使用委托:

创建两个变量用于处理不同高度的伤害

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Movement")
		FVector2D LandedDamageVelocity = FVector2D(900.0f, 1200.0f);
	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Movement")
		FVector2D LandedDamage = FVector2D(10.0f, 100.0f);



	UFUNCTION(BlueprintCallable)
		void OnGroundLanded(const FHitResult& Hit);

使用AddDynamic:动态多播

FMath::Abs():取绝对值

FMath::GetMappedRangeValueClamped(),就是蓝图的MapRangeClamped

TakeDamage:ApplyDamage的底层实现

GetVelocity(),GetCharacterMovement()->Velocity:获取速度

	LandedDelegate.AddDynamic(this, &ASTUBaseCharacter::OnGroundLanded);


void ASTUBaseCharacter::OnGroundLanded(const FHitResult& Hit)
{
    //也可以直接用GetVelocity().Z
	const float FallVelocityZ = FMath::Abs(GetCharacterMovement()->Velocity.Z);

	UE_LOG(BaseCharacterLog, Display, TEXT("Velocity %f "), FallVelocityZ);

	if (FallVelocityZ < LandedDamageVelocity.X)
	{
		return;
	}
	const float FinalDamage = FMath::GetMappedRangeValueClamped(LandedDamageVelocity, LandedDamage, FallVelocityZ);

	TakeDamage(FinalDamage, FDamageEvent{}, nullptr, nullptr);

	UE_LOG(BaseCharacterLog, Display, TEXT("Damage %f "), FinalDamage);

}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UE4中,你可以使用蓝图或C++来生成AI角色。下面是一种使用C++生成AI角色的方法: 1. 创建一个继承自AIController的C++,用于控制AI角色的行为。例如,创建一个名为MyAIController的: ```cpp // MyAIController.h #include "CoreMinimal.h" #include "AIController.h" #include "MyAIController.generated.h" UCLASS() class YOURPROJECT_API AMyAIController : public AAIController { GENERATED_BODY() public: // 构造函数 AMyAIController(); // 在BeginPlay中生成AI角色 virtual void BeginPlay() override; }; ``` 2. 在MyAIController.cpp文件中实现构造函数和BeginPlay函数,并在BeginPlay函数中生成AI角色。例如,使用SpawnActor函数生成AI角色: ```cpp // MyAIController.cpp #include "MyAIController.h" #include "YourAIClass.h" // 替换成你自己的AI角色 AMyAIController::AMyAIController() { // 设置默认Pawn static ConstructorHelpers::FClassFinder<APawn> PawnClass(TEXT("Class'/Script/YourProject.YourAIClass'")); if (PawnClass.Class != nullptr) { DefaultPawnClass = PawnClass.Class; } } void AMyAIController::BeginPlay() { Super::BeginPlay(); // 在这里生成AI角色 GetWorld()->SpawnActor<AYourAIClass>(AYourAIClass::StaticClass(), FVector(0.0f, 0.0f, 0.0f), FRotator::ZeroRotator); } ``` 3. 在UE4编辑器中,创建一个AIController的子蓝图,并将该蓝图指定给你的AI角色。 4. 在关卡中放置一个AIController的子蓝图,并确保它具有与MyAIController对应的。 通过以上步骤,你可以使用C++生成AI角色。根据你的需求,你可以在生成AI角色时设置不同的位置、旋转和其他属性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值