본문 바로가기
Study/Unreal

[Unreal/정리] 인벤토리 On/Off / 캐릭터 HP, MP / 플레이어 데미지 처리

by generous_jeans 2020. 11. 12.

- 인벤토리 -

// x버튼을 눌렀을 때 인벤토리가 삭제되도록 설정. 

(언리얼 에디터-Inventory) Button : "CloseButton" 이미지 설정 Draw as : "Image" (0.9 1.0 0.7) 변수인지 : "해제"

 

(C++-Inventory.h) 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "Inventory.generated.h"

/**
 * 
 */
UCLASS()
class UE7PROJECT_API UInventory : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UListView* List;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* CloseButton;

protected:
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

public:
    UFUNCTION(BlueprintCallable)
    void InitList();
    
    UFUNCTION(BlueprintCallable)
    void ItemClick(UObject* Obj);

    UFUNCTION(BlueprintCallable)
    void CloseButtonClick();
    
};

(C++-Inventory.cpp) 

// Fill out your copyright notice in the Description page of Project Settings.


#include "Inventory.h"
#include "Components/ListView.h"
#include "InventoryItemData.h"
#include "WukongController.h"
#include "PlayerCharacter.h"
#include "Components/Button.h"

void UInventory::NativeConstruct()
{
    Super::NativeConstruct();

    List = Cast<UListView>(GetWidgetFromName(TEXT("InventoryList")));
    CloseButton = Cast<UButton>(GetWidgetFromName(TEXT("CloseButton")));

    List->OnItemClicked().AddUObject(this, &UInventory::ItemClick);
    CloseButton->OnClicked.AddDynamic(this, &UInventory::CloseButtonClick);

    InitList();
}

void UInventory::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
	Super::NativeTick(MyGeometry, InDeltaTime);
}

void UInventory::InitList()
{
    for (int32 i = 0; i < 2000; ++i)
    {
        UInventoryItemData* Data = NewObject<UInventoryItemData>(this, UInventoryItemData::StaticClass());

        Data->SetItemIndex(i);
        Data->SetItemCount(1);
		
        switch (FMath::RandRange(0, 2))
        {
        case 0:
            Data->SetItemName(TEXT("Weapon1"));
            Data->SetIconTexture(TEXT("Texture2D'/Game/UI/T_UI_Weapon_Sword.T_UI_Weapon_Sword'"));
            Data->SetMeshPath(TEXT("SkeletalMesh'/Game/InfinityBladeWeapons/Weapons/Blade/Swords/Blade_BlackKnight/SK_Blade_BlackKnight.SK_Blade_BlackKnight'"));
			break;
        case 1:
            Data->SetItemName(TEXT("Weapon2"));
            Data->SetIconTexture(TEXT("Texture2D'/Game/UI/T_UI_Icon_PotMana01.T_UI_Icon_PotMana01'"));
            Data->SetMeshPath(TEXT("SkeletalMesh'/Game/InfinityBladeWeapons/Weapons/Blunt/Blunt_Primative/SK_Blunt_Primative.SK_Blunt_Primative'"));
            break;
        case 2:
            Data->SetItemName(TEXT("Weapon3"));
            Data->SetIconTexture(TEXT("Texture2D'/Game/UI/T_UI_Weapon_Axe.T_UI_Weapon_Axe'"));
            Data->SetMeshPath(TEXT("SkeletalMesh'/Game/InfinityBladeWeapons/Weapons/Dual_Blade/Dual_Blade_SwordOfStorms/SK_Dual_Blade_SwordOfStorms.SK_Dual_Blade_SwordOfStorms'"));
            break;
        }

        List->AddItem(Data);
     
         //List->RemoveItem();
    }
}

void UInventory::ItemClick(UObject* Obj)
{
    PrintViewport(2.f, FColor::Red, TEXT("ItemClick"));

    UInventoryItemData* pData = Cast<UInventoryItemData>(Obj);

    if (IsValid(pData))
    {
        AWukongController* Controller = Cast<AWukongController>(GetWorld()->GetFirstPlayerController());
    
        if (IsValid(Controller))
        {
            APlayerCharacter* PlayerChar = Cast<APlayerCharacter>(Controller->GetPawn());

            if (IsValid(PlayerChar))
                PlayerChar->ChangeWeapon(pData->GetMeshPath());
        }
    }
}

void UInventory::CloseButtonClick()  // CloseButton을 누르면 인벤토리 위젯을 안보이도록 설정. 
{
    SetVisibility(ESlateVisibility::Collapsed);
}

 

// 인벤토리 버튼을 눌렀을 때 인벤토리가 뜨도록 설정.

(C++-MainHUDWidget.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "MainHUDWidget.generated.h"

UCLASS()
class UE7PROJECT_API UMainHUDWidget : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* OptionButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* InventoryButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* CharacterStateButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UInventory* Inventory;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UCharacterStateHUD* CharacterState;

protected:
    virtual void NativePreConstruct();
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

private:
    UFUNCTION(BlueprintCallable)
    void OptionButtonCallback();

    UFUNCTION(BlueprintCallable)
    void InventoryButtonCallback();

    UFUNCTION(BlueprintCallable)
    void CharacterStateButtonCallback();

public:
    void SetPlayerHP(float fPercent);
    void SetPlayerMP(float fPercent);
    void SetPlayerName(const FString& strName);
    
};

(C++-MainHUDWidget.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MainHUDWidget.h"
#include "Components/Button.h"
#include "Inventory.h"
#include "CharacterStateHUD.h"

void UMainHUDWidget::NativePreConstruct()
{
    Super::NativePreConstruct();
    
    OptionButton = Cast<UButton>(GetWidgetFromName(TEXT("OptionButton")));
    InventoryButton = Cast<UButton>(GetWidgetFromName(TEXT("InventoryButton")));
    CharacterStateButton = Cast<UButton>(GetWidgetFromName(TEXT("CharacterStateButton")));
    Inventory = Cast<UInventory>(GetWidgetFromName(TEXT("UI_Inventory")));
    CharacterState = Cast<UCharacterStateHUD>(GetWidgetFromName(TEXT("UI_CharStateHUD")));

    OptionButton->OnClicked.AddDynamic(this, &UMainHUDWidget::OptionButtonCallback);
    InventoryButton->OnClicked.AddDynamic(this, &UMainHUDWidget::InventoryButtonCallback);
    CharacterStateButton->OnClicked.AddDynamic(this, &UMainHUDWidget::CharacterStateButtonCallback);
}

void UMainHUDWidget::NativeConstruct()
{
    Super::NativeConstruct();
}

void UMainHUDWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UMainHUDWidget::OptionButtonCallback()
{
}

void UMainHUDWidget::InventoryButtonCallback()
{
    PrintViewport(1.f, FColor::Red, TEXT("InvenButton"));
    switch (Inventory->GetVisibility())
    {
    case ESlateVisibility::Visible:
        Inventory->SetVisibility(ESlateVisibility::Collapsed);
        break;
    case ESlateVisibility::Collapsed:
        Inventory->SetVisibility(ESlateVisibility::Visible);
        break;
    }
}

void UMainHUDWidget::CharacterStateButtonCallback()
{
}

void UMainHUDWidget::SetPlayerHP(float fPercent)
{
    CharacterState->SetHP(fPercent);
}

void UMainHUDWidget::SetPlayerMP(float fPercent)
{
    CharacterState->SetMP(fPercent);
}

void UMainHUDWidget::SetPlayerName(const FString& strName)
{
    CharacterState->SetNameText(strName);
}

 

 

(언리얼 에디터-MainHUD) UIInventory-변수인지 : "해제"

 

- 캐릭터 HP, MP - 

(언리얼 에디터) UI -> 우클릭_유저 인터페이스_위젯 블루프린트 : "UI_CharStateHUD"

 

(언리얼 에디터-UI_CharStateHUD) 너비 : "300" 하이트 : "200"

(언리얼 에디터-UI_CharStateHUD) Image : "Back" 이미지 설정 

(언리얼 에디터-UI_CharStateHUD) Text : "Name"

(언리얼 에디터-UI_CharStateHUD) Progress Bar : Back보다 위에 위치하도록 설정 FillImage : 이미지 설정

(언리얼 에디터-UI_CharStateHUD) Progress Bar : Back보다 위에 위치하도록 설정 FillImage : 이미지 설정

 

(언리얼 에디터) C++클래스  -> 우클릭_새 C++클래스 -> 부모 : "UserWidget" 이름 : "CharacterStateHUD"

 

(C++-CharacterStateHUD.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "CharacterStateHUD.generated.h"


UCLASS()
class UE7PROJECT_API UCharacterStateHUD : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UTextBlock* NameText;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UProgressBar* HPBar;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UProgressBar* MPBar;

protected:
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

public:
    void SetHP(float fPercent);
    void SetMP(float fPercent);
    void SetNameText(const FString& strText);

};

(C++-CharacterStateHUD.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "CharacterStateHUD.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"

void UCharacterStateHUD::NativeConstruct()
{
    Super::NativeConstruct();
    
    NameText = Cast<UTextBlock>(GetWidgetFromName(TEXT("Name")));
    HPBar = Cast<UProgressBar>(GetWidgetFromName(TEXT("HP")));
    MPBar = Cast<UProgressBar>(GetWidgetFromName(TEXT("MP")));
}

void UCharacterStateHUD::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UCharacterStateHUD::SetHP(float fPercent)
{
    HPBar->SetPercent(fPercent);
}

void UCharacterStateHUD::SetMP(float fPercent)
{
    MPBar->SetPercent(fPercent);
}

void UCharacterStateHUD::SetNameText(const FString& strText)
{
    NameText->SetText(FText::FromString(strText));
}

(언리얼 에디터-UI_CharStateHUD) 부모 클래스 : "CharacterStateHUD"

 

(언리얼 에디터-MainHUD) 사용자 생성 : UI_CharStateHUD 배치 변수인지 : "해제"

 

- 플레이어가 공격을 받을 때 데미지 처리 - 

(언리얼 에디터-BPMinonAnim) Attack-노티파이 추가 : "Damage"

 

(C++-MinionAnim.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Animation/AnimInstance.h"
#include "MinionAnim.generated.h"

UENUM(BlueprintType, Meta = (Bitflags))
enum class EMinionAnim : uint8
{
    Idle,
    Run,
    Attack,
    Hit,
    Death
};

UCLASS()
class UE7PROJECT_API UMinionAnim : public UAnimInstance
{
    GENERATED_BODY()

public:
    UMinionAnim();

protected:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true", Bitmask, BitmaskEnum = "EMonsterAnim"))
    uint8 AnimType;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    bool MoveStop;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    bool IsGround;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    bool AttackEnable;

public:
    virtual void NativeInitializeAnimation();
    virtual void NativeUpdateAnimation(float DeltaSeconds);

public:
    void ChangeAnim(EMonsterAnim eAnim);

public:
    UFUNCTION()
    void AnimNotify_AttackEnd();

    UFUNCTION()
    void AnimNotify_DeathEnd();

    UFUNCTION()
    void AnimNotify_Damage();
    
};

(C++-MinionAnim.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MinionAnim.h"
#include "Minion.h"
#include "MonsterAIController.h"

UMinionAnim::UMinionAnim()
{
    MoveStop = true;
    AttackEnable = true;
    IsGround = true;

    AnimType = (uint8)EMonsterAnim::Idle;
}

void UMinionAnim::NativeInitializeAnimation()
{
    Super::NativeInitializeAnimation();
}

void UMinionAnim::NativeUpdateAnimation(float DeltaSeconds)
{
    Super::NativeUpdateAnimation(DeltaSeconds);

    AMinion* pOwner = Cast<AMinion>(TryGetPawnOwner());

    if (IsValid(pOwner))
    {
        // Movement를 얻어온다.
        UCharacterMovementComponent* pMovement = pOwner->GetCharacterMovement();

        if (IsValid(pMovement))
        {
            IsGround = pMovement->IsMovingOnGround();

            if (IsGround)
            {
                // 움직이고 있을때
                if (pMovement->Velocity.Size() > 0.f)
                {
                    MoveStop = false;

                    AnimType = (uint8)EMonsterAnim::Run;
                }
                // 멈췄을때
                else
                {
                    MoveStop = true;
                }
            }
        }
    }
}

void UMinionAnim::ChangeAnim(EMonsterAnim eAnim)
{
    AnimType = (uint8)eAnim;
}

void UMinionAnim::AnimNotify_AttackEnd()
{
    AMinion* pOwner = Cast<AMinion>(TryGetPawnOwner());

    if (IsValid(pOwner))
        pOwner->AttackEnd();
}

void UMinionAnim::AnimNotify_DeathEnd()
{
    AMinion* pOwner = Cast<AMinion>(TryGetPawnOwner());

    if (IsValid(pOwner))
        pOwner->Death();
}

void UMinionAnim::AnimNotify_Damage()
{
    AMinion* pOwner = Cast<AMinion>(TryGetPawnOwner());

    if (IsValid(pOwner))
    {
        AMonsterAIController* AI = pOwner->GetController<AMonsterAIController>();
    
        if (IsValid(AI))
        {
            ACharacter* Target = AI->GetTarget();

            FDamageEvent DamageEvent;
            Target->TakeDamage(pOwner->GetAttackPoint(), DamageEvent, AI, pOwner);
        }
    }
}

(C++-MonsterAIController.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "AIController.h"
#include "MonsterAIController.generated.h"

/**
 * 
 */
UCLASS()
class UE7PROJECT_API AMonsterAIController : public AAIController
{
    GENERATED_BODY()
	
public:
    AMonsterAIController();

protected:
    UBehaviorTree* m_pBTAsset;
    UBlackboardData* m_pBBAsset;
    ACharacter* m_pTarget;

protected:
    virtual void OnPossess(APawn* InPawn) override;
    virtual void OnUnPossess() override;

public:
    void SetTarget(UObject* pTarget);
    ACharacter* GetTarget() const;
    
};

(C++-MonsterAIController.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MonsterAIController.h"
#include "BehaviorTree/BehaviorTree.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "BehaviorTree/BlackboardData.h"
#include "BehaviorTree/BlackboardComponent.h"
#include "Monster.h"

AMonsterAIController::AMonsterAIController()
{
    static ConstructorHelpers::FObjectFinder<UBehaviorTree> BTAsset(TEXT("BehaviorTree'/Game/Monster/BTMonster.BTMonster'"));

    if (BTAsset.Succeeded())
        m_pBTAsset = BTAsset.Object;

    static ConstructorHelpers::FObjectFinder<UBlackboardData> BBAsset(TEXT("BlackboardData'/Game/Monster/BBMonster.BBMonster'"));

    if (BBAsset.Succeeded())
        m_pBBAsset = BBAsset.Object;

    m_pTarget = nullptr;
}

void AMonsterAIController::OnPossess(APawn* InPawn)
{
    Super::OnPossess(InPawn);

    // 사용하려는 블랙보드를 지정한다.
    if (UseBlackboard(m_pBBAsset, Blackboard))
    {
        // 행동트리를 지정하고 동작하게 한다.
        if (!RunBehaviorTree(m_pBTAsset))
        {
        }
    }
}

void AMonsterAIController::OnUnPossess()
{
    Super::OnUnPossess();
}

void AMonsterAIController::SetTarget(UObject* pTarget)
{
    Blackboard->SetValueAsObject(TEXT("Target"), pTarget);

    if (pTarget)
        m_pTarget = Cast<ACharacter>(pTarget);
    else
        m_pTarget = nullptr;
}

ACharacter* AMonsterAIController::GetTarget() const
{
    return m_pTarget;
}

(C++-PlayerCharcter.h)

// 플레이어 능력치 설정. 

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "GameFramework/Character.h"
#include "PlayerCharacter.generated.h"

USTRUCT(Atomic, BlueprintType)
struct FCharacterState
{
    GENERATED_USTRUCT_BODY()

public:
    FCharacterState()
    {
    }

public:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    FString	strName;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fAttack;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fArmor;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iHP;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iHPMax;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iMP;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    int32 iMPMax;
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fAttackDist;
};

UCLASS()
class UE7PROJECT_API APlayerCharacter : public ACharacter
{
    GENERATED_BODY()

public:
    // Sets default values for this character's properties
    APlayerCharacter();

protected:
    bool bStartAnimation;

    UPROPERTY(Category = Item, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    class AWeapon* Weapon;

    UPROPERTY(Category = Item, EditAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
    FCharacterState	CharacterState;

public:
    FCharacterState GetCharacterState()
    {
        return CharacterState;
    }

public:
    void StartAnimation()
    {
        bStartAnimation = true;
    }

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;
    virtual float TakeDamage(float DamageAmount, struct FDamageEvent const& DamageEvent, class AController* EventInstigator, AActor* DamageCauser);

public:
    void ChangeWeapon(const FString& strPath);
    
};

 

(C++-PlayeCharacter.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerCharacter.h"
#include "Weapon.h"
#include "MainHUDWidget.h"
#include "MainGameMode.h"

// Sets default values
APlayerCharacter::APlayerCharacter()
{
    // 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;
    
    bStartAnimation = false;

    GetMesh()->SetReceivesDecals(false);
}

// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
	
}

// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

float APlayerCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
    float fDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
    
    CharacterState.iHP -= (int32)DamageAmount;
    
    if (CharacterState.iHP < 0)
    {
        CharacterState.iHP = 0;
    }

    AMainGameMode* GameMode = Cast<AMainGameMode>(GetWorld()->GetAuthGameMode());

    if (IsValid(GameMode))
    {
        UMainHUDWidget* MainWidget = GameMode->GetMainHUDWidget();

        if (IsValid(MainWidget))
            MainWidget->SetPlayerHP(CharacterState.iHP / (float)CharacterState.iHPMax);
    }

    return fDamage;
}

void APlayerCharacter::ChangeWeapon(const FString& strPath)
{
    Weapon->LoadMesh(strPath);
}

 

(언리얼 에디터) Monster -> 우클릭_데이터 테이블 : "

 

(C++-Wukong.cpp)

// Wukong 능력치 설정. 

 

// Fill out your copyright notice in the Description page of Project Settings.


#include "Wukong.h"
#include "WukongAnim.h"
#include "Weapon.h"
#include "EffectDestroy.h"
#include "DrawDebugHelpers.h"

// Sets default values
AWukong::AWukong()
{
    // 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;

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Arm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Arm"));

    Arm->SetupAttachment(GetMesh());
    Camera->SetupAttachment(Arm);

    // 애니메이션 클래스 지정
    static ConstructorHelpers::FClassFinder<UWukongAnim> AnimAsset(TEXT("AnimBlueprint'/Game/Player/BPWukongAnim.BPWukongAnim_C'"));

    if (AnimAsset.Succeeded())
        GetMesh()->SetAnimInstanceClass(AnimAsset.Class);


    Weapon = nullptr;

    GetCapsuleComponent()->SetCollisionProfileName(TEXT("Player"));

    WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponBox"));

    WeaponBox->SetupAttachment(GetMesh(), TEXT("FX_Staff_Mid"));

    WeaponBox->SetCollisionProfileName(TEXT("PlayerAttack"));

    WeaponBox->SetBoxExtent(FVector(120.f, 10.f, 10.f));

    static ConstructorHelpers::FClassFinder<AProjectileSkill> ProjectileAsset(TEXT("Blueprint'/Game/Skill/BPProjectileSkill.BPProjectileSkill_C'"));

    if (ProjectileAsset.Succeeded())
        ProjectileSkillClass = ProjectileAsset.Class;

    CharacterState.fAttack = 20.f;
    CharacterState.fArmor = 10.f;
    CharacterState.iHP = 500;
    CharacterState.iHPMax = 500;
    CharacterState.iMP = 100;
    CharacterState.iMPMax = 100;
    CharacterState.fAttackDist = 150.f;
    
}
...

(C++-MainHUDWidget.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "MainHUDWidget.generated.h"

UCLASS()
class UE7PROJECT_API UMainHUDWidget : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* OptionButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* InventoryButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* CharacterStateButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UInventory* Inventory;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UCharacterStateHUD* CharacterState;

protected:
    virtual void NativePreConstruct();
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

private:
    UFUNCTION(BlueprintCallable)
    void OptionButtonCallback();

    UFUNCTION(BlueprintCallable)
    void InventoryButtonCallback();

    UFUNCTION(BlueprintCallable)
    void CharacterStateButtonCallback();

public:
    void SetPlayerHP(float fPercent);
    void SetPlayerMP(float fPercent);
    void SetPlayerName(const FString& strName);
    
};

(C++-MainHUDWidget.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MainHUDWidget.h"
#include "Components/Button.h"
#include "Inventory.h"
#include "CharacterStateHUD.h"

void UMainHUDWidget::NativePreConstruct()
{
    Super::NativePreConstruct();
    
    OptionButton = Cast<UButton>(GetWidgetFromName(TEXT("OptionButton")));
    InventoryButton = Cast<UButton>(GetWidgetFromName(TEXT("InventoryButton")));
    CharacterStateButton = Cast<UButton>(GetWidgetFromName(TEXT("CharacterStateButton")));
    Inventory = Cast<UInventory>(GetWidgetFromName(TEXT("UI_Inventory")));
    CharacterState = Cast<UCharacterStateHUD>(GetWidgetFromName(TEXT("UI_CharStateHUD")));

    OptionButton->OnClicked.AddDynamic(this, &UMainHUDWidget::OptionButtonCallback);
    InventoryButton->OnClicked.AddDynamic(this, &UMainHUDWidget::InventoryButtonCallback);
    CharacterStateButton->OnClicked.AddDynamic(this, &UMainHUDWidget::CharacterStateButtonCallback);
}

void UMainHUDWidget::NativeConstruct()
{
    Super::NativeConstruct();
}

void UMainHUDWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UMainHUDWidget::OptionButtonCallback()
{
}

void UMainHUDWidget::InventoryButtonCallback()
{
    PrintViewport(1.f, FColor::Red, TEXT("InvenButton"));
    switch (Inventory->GetVisibility())
    {
    case ESlateVisibility::Visible:
        Inventory->SetVisibility(ESlateVisibility::Collapsed);
        break;
    case ESlateVisibility::Collapsed:
        Inventory->SetVisibility(ESlateVisibility::Visible);
        break;
    }
}

void UMainHUDWidget::CharacterStateButtonCallback()
{
}

void UMainHUDWidget::SetPlayerHP(float fPercent)
{
    CharacterState->SetHP(fPercent);
}

void UMainHUDWidget::SetPlayerMP(float fPercent)
{
    CharacterState->SetMP(fPercent);
}

void UMainHUDWidget::SetPlayerName(const FString& strName)
{
    CharacterState->SetNameText(strName);
}

 

 

- 플레리어 이름 출력 -

(C++-CharactreStateHUD.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "CharacterStateHUD.generated.h"


UCLASS()
class UE7PROJECT_API UCharacterStateHUD : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UTextBlock* NameText;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UProgressBar* HPBar;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UProgressBar* MPBar;

protected:
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

public:
    void SetHP(float fPercent);
    void SetMP(float fPercent);
    void SetNameText(const FString& strText);
    
};

(C++-CharacterStateHUD.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "CharacterStateHUD.h"
#include "Components/ProgressBar.h"
#include "Components/TextBlock.h"

void UCharacterStateHUD::NativeConstruct()
{
    Super::NativeConstruct();

    NameText = Cast<UTextBlock>(GetWidgetFromName(TEXT("Name")));
    HPBar = Cast<UProgressBar>(GetWidgetFromName(TEXT("HP")));
    MPBar = Cast<UProgressBar>(GetWidgetFromName(TEXT("MP")));
}

void UCharacterStateHUD::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UCharacterStateHUD::SetHP(float fPercent)
{
    HPBar->SetPercent(fPercent);
}

void UCharacterStateHUD::SetMP(float fPercent)
{
    MPBar->SetPercent(fPercent);
}

void UCharacterStateHUD::SetNameText(const FString& strText)
{
    NameText->SetText(FText::FromString(strText));
}

(C++-MainGameMode.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MainGameMode.h"
#include "Wukong.h"
#include "WukongController.h"
#include "UE7GameInstance.h"
#include "MainHUDWidget.h"

AMainGameMode::AMainGameMode()
{
    static ConstructorHelpers::FClassFinder<UUserWidget> MainHUDWidgetAsset(TEXT("WidgetBlueprint'/Game/UI/UI_MainHUD.UI_MainHUD_C'"));

    if (MainHUDWidgetAsset.Succeeded())
        MainHUDWidgetClass = MainHUDWidgetAsset.Class;
}

void AMainGameMode::BeginPlay()
{
    Super::BeginPlay();

    if (IsValid(MainHUDWidgetClass))
    {
        MainHUDWidget = Cast<UMainHUDWidget>(CreateWidget(GetWorld(), MainHUDWidgetClass));

        if (MainHUDWidget)
        {
            MainHUDWidget->AddToViewport();

            UUE7GameInstance* GameInst = Cast<UUE7GameInstance>(GetGameInstance());
            FString	strName = GameInst->GetSelectPlayerName();

            MainHUDWidget->SetPlayerName(strName);
        }
    }
}

(C++-PlayeCharacter.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "PlayerCharacter.h"
#include "Weapon.h"
#include "MainHUDWidget.h"
#include "MainGameMode.h"

// Sets default values
APlayerCharacter::APlayerCharacter()
{
    // 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;
    
    bStartAnimation = false;

    GetMesh()->SetReceivesDecals(false);
}

// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
	
}

// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);

}

// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);

}

float APlayerCharacter::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
    float fDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);
    
    CharacterState.iHP -= (int32)DamageAmount;
    
    if (CharacterState.iHP < 0)
    {
        CharacterState.iHP = 0;
    }

    AMainGameMode* GameMode = Cast<AMainGameMode>(GetWorld()->GetAuthGameMode());

    if (IsValid(GameMode))
    {
        UMainHUDWidget* MainWidget = GameMode->GetMainHUDWidget();

        if (IsValid(MainWidget))
            MainWidget->SetPlayerHP(CharacterState.iHP / (float)CharacterState.iHPMax);
    }

    return fDamage;
}

void APlayerCharacter::ChangeWeapon(const FString& strPath)
{
    Weapon->LoadMesh(strPath);
}

 

(C++-Wukong.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "Wukong.h"
#include "WukongAnim.h"
#include "Weapon.h"
#include "EffectDestroy.h"
#include "DrawDebugHelpers.h"

// Sets default values
AWukong::AWukong()
{
    // 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;

    Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera"));
    Arm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Arm"));

    Arm->SetupAttachment(GetMesh());
    Camera->SetupAttachment(Arm);

    // 애니메이션 클래스 지정
    static ConstructorHelpers::FClassFinder<UWukongAnim> AnimAsset(TEXT("AnimBlueprint'/Game/Player/BPWukongAnim.BPWukongAnim_C'"));

    if (AnimAsset.Succeeded())
        GetMesh()->SetAnimInstanceClass(AnimAsset.Class);


    Weapon = nullptr;

    GetCapsuleComponent()->SetCollisionProfileName(TEXT("Player"));

    WeaponBox = CreateDefaultSubobject<UBoxComponent>(TEXT("WeaponBox"));

    WeaponBox->SetupAttachment(GetMesh(), TEXT("FX_Staff_Mid"));

    WeaponBox->SetCollisionProfileName(TEXT("PlayerAttack"));

    WeaponBox->SetBoxExtent(FVector(120.f, 10.f, 10.f));

    static ConstructorHelpers::FClassFinder<AProjectileSkill> ProjectileAsset(TEXT("Blueprint'/Game/Skill/BPProjectileSkill.BPProjectileSkill_C'"));

    if (ProjectileAsset.Succeeded())
        ProjectileSkillClass = ProjectileAsset.Class;

    CharacterState.fAttack = 20.f;
    CharacterState.fArmor = 10.f;
    CharacterState.iHP = 500;
    CharacterState.iHPMax = 500;
    CharacterState.iMP = 100;
    CharacterState.iMPMax = 100;
    CharacterState.fAttackDist = 150.f;
    
}
...

(C++-MainHUDWidget.h)

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "GameInfo.h"
#include "Blueprint/UserWidget.h"
#include "MainHUDWidget.generated.h"

UCLASS()
class UE7PROJECT_API UMainHUDWidget : public UUserWidget
{
    GENERATED_BODY()

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* OptionButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* InventoryButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UButton* CharacterStateButton;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UInventory* Inventory;

    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UCharacterStateHUD* CharacterState;

protected:
    virtual void NativePreConstruct();
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

private:
    UFUNCTION(BlueprintCallable)
    void OptionButtonCallback();

    UFUNCTION(BlueprintCallable)
    void InventoryButtonCallback();

    UFUNCTION(BlueprintCallable)
    void CharacterStateButtonCallback();

public:
    void SetPlayerHP(float fPercent);
    void SetPlayerMP(float fPercent);
    void SetPlayerName(const FString& strName);
    
};

(C++-MainHUDWidget.cpp)

// Fill out your copyright notice in the Description page of Project Settings.


#include "MainHUDWidget.h"
#include "Components/Button.h"
#include "Inventory.h"
#include "CharacterStateHUD.h"

void UMainHUDWidget::NativePreConstruct()
{
    Super::NativePreConstruct();
    
    OptionButton = Cast<UButton>(GetWidgetFromName(TEXT("OptionButton")));
    InventoryButton = Cast<UButton>(GetWidgetFromName(TEXT("InventoryButton")));
    CharacterStateButton = Cast<UButton>(GetWidgetFromName(TEXT("CharacterStateButton")));
    Inventory = Cast<UInventory>(GetWidgetFromName(TEXT("UI_Inventory")));
    CharacterState = Cast<UCharacterStateHUD>(GetWidgetFromName(TEXT("UI_CharStateHUD")));

    OptionButton->OnClicked.AddDynamic(this, &UMainHUDWidget::OptionButtonCallback);
    InventoryButton->OnClicked.AddDynamic(this, &UMainHUDWidget::InventoryButtonCallback);
    CharacterStateButton->OnClicked.AddDynamic(this, &UMainHUDWidget::CharacterStateButtonCallback);
}

void UMainHUDWidget::NativeConstruct()
{
    Super::NativeConstruct();
}

void UMainHUDWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
{
    Super::NativeTick(MyGeometry, InDeltaTime);
}

void UMainHUDWidget::OptionButtonCallback()
{
}

void UMainHUDWidget::InventoryButtonCallback()
{
    PrintViewport(1.f, FColor::Red, TEXT("InvenButton"));
    switch (Inventory->GetVisibility())
    {
    case ESlateVisibility::Visible:
        Inventory->SetVisibility(ESlateVisibility::Collapsed);
        break;
    case ESlateVisibility::Collapsed:
        Inventory->SetVisibility(ESlateVisibility::Visible);
        break;
    }
}

void UMainHUDWidget::CharacterStateButtonCallback()
{
}

void UMainHUDWidget::SetPlayerHP(float fPercent)
{
    CharacterState->SetHP(fPercent);
}

void UMainHUDWidget::SetPlayerMP(float fPercent)
{
    CharacterState->SetMP(fPercent);
}

void UMainHUDWidget::SetPlayerName(const FString& strName)
{
    CharacterState->SetNameText(strName);
}

 

'Study > Unreal' 카테고리의 다른 글

[Unreal/정리] 보스존 트리거  (0) 2020.11.14
[Unreal/정리] 카메라 쉐이크 / 트리거  (0) 2020.11.13
[Unreal/정리] UI_아이템  (0) 2020.11.10
[Unreal/정리] 캐릭터 선택  (0) 2020.11.09
[Unreal/정리] 시작 화면  (0) 2020.11.05

댓글