UE4 技能系统训练教程
// CharacterBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
#include "Abilities/GameplayAbility.h"
#include "CharacterBase.generated.h"
class UAttributeSetBase;
UCLASS()
class ABILITYSYSTEM_API ACharacterBase : public ACharacter, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
// Sets default values for this character's properties
ACharacterBase();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "CharacterBase")
UAbilitySystemComponent* AbilitySystemComp;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "CharacterBase")
UAttributeSetBase * AttributeSetBaseComp;
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const;
UFUNCTION(BlueprintCallable, Category = "CharacterBase")
void AquireAbility(TSubclassOf<UGameplayAbility> AbilityToAquire);
UFUNCTION()
void OnHealthChanged(float Health, float MaxHealth);
UFUNCTION(BlueprintImplementableEvent, Category = "CharacterBase", meta = (DisplayName = "OnHealthChanged"))
void BP_OnHealthChanged(float Health, float MaxHealth);
UFUNCTION(BlueprintImplementableEvent, Category = "CharacterBase", meta = (DisplayName = "Die"))
void BP_Die();
UFUNCTION(BlueprintCallable, Category = "CharacterBase")
bool IsOtherHostile(ACharacterBase * Other);
uint8 GetTeamID() const;
protected:
bool bIsDead;
uint8 TeamID;
void AutoDeterminTeamIDbyControllerType();
void Dead();
};
// CharacterBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "CharacterBase.h"
# include "AttributeSetBase.h"
# include "GameFramework/PlayerController.h"
# include "AIController.h"
# include "BrainComponent.h"
// Sets default values
ACharacterBase::ACharacterBase()
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
AbilitySystemComp = CreateDefaultSubobject<UAbilitySystemComponent>("AbilitySystemComp");
AttributeSetBaseComp = CreateDefaultSubobject<UAttributeSetBase>("AttributeSetBaseComp");
bIsDead = false;
TeamID = 255;
}
// Called when the game starts or when spawned
void ACharacterBase::BeginPlay()
{
Super::BeginPlay();
AttributeSetBaseComp->OnHealthChange.AddDynamic(this, &ACharacterBase::OnHealthChanged);
AutoDeterminTeamIDbyControllerType();
}
// Called every frame
void ACharacterBase::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ACharacterBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
UAbilitySystemComponent * ACharacterBase::GetAbilitySystemComponent() const
{
return AbilitySystemComp;
}
void ACharacterBase::AquireAbility(TSubclassOf<UGameplayAbility> AbilityToAquire)
{
if (AbilitySystemComp)
{
if (HasAuthority() && AbilityToAquire)
{
AbilitySystemComp->GiveAbility(FGameplayAbilitySpec(AbilityToAquire, 1, 0));
}
AbilitySystemComp->InitAbilityActorInfo(this, this);
}
}
void ACharacterBase::OnHealthChanged(float Health, float MaxHealth)
{
if (Health<= 0.0f && !bIsDead)
{
bIsDead = true;
Dead();
BP_Die();
}
BP_OnHealthChanged(Health, MaxHealth);
}
bool ACharacterBase::IsOtherHostile(ACharacterBase * Other)
{
return TeamID != Other->GetTeamID();
}
uint8 ACharacterBase::GetTeamID() const
{
return TeamID;
}
void ACharacterBase::AutoDeterminTeamIDbyControllerType()
{
if (GetController() && GetController()->IsPlayerController())
TeamID = 0;
{
}
}
void ACharacterBase::Dead()
{
APlayerController * PC = Cast <APlayerController>(GetController());
if (PC)
{
PC->DisableInput(PC);
}
AAIController * AIC = Cast<AAIController>(GetController());
if (AIC)
{
AIC->GetBrainComponent()->StopLogic("Dead");
}
}
//AttributeSetBase.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AttributeSetBase.generated.h"
/**
*
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnHealthChangeDelegate, float, Health, float, MaxHealth);
UCLASS()
class ABILITYSYSTEM_API UAttributeSetBase : public UAttributeSet
{
GENERATED_BODY()
public:
UAttributeSetBase();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AttributeSetBase")
FGameplayAttributeData Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AttributeSetBase")
FGameplayAttributeData MaxHealth;
void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData &Data) override;
FOnHealthChangeDelegate OnHealthChange;
};
// AttributeSetBase.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "AttributeSetBase.h"
# include "GameplayEffectExtension.h"
# include "GameplayEffect.h"
UAttributeSetBase::UAttributeSetBase()
:Health(200.0f),
MaxHealth(200.0f)
{
}
void UAttributeSetBase::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData & Data)
{
if (Data.EvaluatedData.Attribute.GetUProperty() == FindFieldChecked<UProperty>(UAttributeSetBase::StaticClass(), GET_MEMBER_NAME_CHECKED(UAttributeSetBase, Health)))
{
Health.SetCurrentValue(FMath::Clamp(Health.GetCurrentValue(), 0.f, MaxHealth.GetCurrentValue()));
Health.SetBaseValue(FMath::Clamp(Health.GetBaseValue(), 0.f, MaxHealth.GetCurrentValue()));
UE_LOG(LogTemp, Warning, TEXT("Ouch, I took some damage, now my health is :%f"), Health.GetCurrentValue());
OnHealthChange.Broadcast(Health.GetCurrentValue(), MaxHealth.GetCurrentValue());
}
}
//AbilitySystem.Build.cs
// Copyright 1998-2018 Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class AbilitySystem : ModuleRules
{
public AbilitySystem(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay","GameplayAbilities", "GamePlayTags", "GameplayTasks", "AIModule" });
}
}