본문 바로가기
Study/Unreal

[Unreal/정리] HPBar

by generous_jeans 2020. 11. 4.

[ UMG ] 

(C++-UE7Project.Build.cs)

// Copyright Epic Games, Inc. All Rights Reserved.

using UnrealBuildTool;

public class UE7Project : ModuleRules
{
    public UE7Project(ReadOnlyTargetRules Target) : base(Target)
    {
        PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
        PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "ApexDestruction", "AIModule", "GameplayTasks", "NavigationSystem", "UMG" });

        PrivateDependencyModuleNames.AddRange(new string[] {  });  
    }
}

 

[ UI-HPBar ]

: 몬스터의 머리위에 HPBar를 배치.

 

(언리얼 에디터) 신규 추가 -> 새 폴더 -> "UI"

 

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

// Screen : 2D 화면 상에 위치하는 것.

// World : 3D 공간에 배치되는 것. 

 

// HPBar를 2D로 할 경우, 카메라가 아래에 있거나 위에 있을 경우 기울어지게 보이게 됨.

// 다른 것의 뒤에 플레이어가 위치했을 때 HPBar가 숨겨지지 않고 보이게 됨. 2D는 깊이값이 없기 때문.

// HPBar를 3D로 할 경우, 플레이어가 회전을 하면 HPBar도 같이 회전해서 보이지 않게 됨. 

// 보통 2D를 사용함. 

 

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

 

(언리얼 에디터-UI_HPBar) 그래프 -> 클래스 세팅 -> 디테일-클래스 옵션-부모 클래스 : "UIHPBar"

 

(언리얼 에디터-UI_HPBar) Canvas Panel 삭제

 

(언리얼 에디터-UI_HPBar) 디자이너 -> 팔레트-일반-Progress Bar : "HPBar"

(언리얼 에디터-UI_HPBar) HPBar -> 디테일-변수인지 : "해제" 

(언리얼 에디터-UI_HPBar) HPBar -> 디테일-슬롯-X 위치 : "0" Y 위치 : "0" X 크기 : "200" Y 크기 : "50"

// Progress Bar -> 디테일-Progress-Percent : 색이 채워지는 것을 조절. 

// Progress Bar -> 디테일-Progress-Percent-바인드-바인딩 생성 : 이 Progress Bar에 영향을 줄 변수를 세팅할 수 있음. 

 

(언리얼 에디터-UI_HPBar) 화면크기 -> Custom-너비 : "200" 하이트 : "50"

 

(언리얼 에디터-UI_HPBar) HPBar -> 우클릭_다음으로 래핑-Vertical Box

(언리얼 에디터-UI_HPBar) 팔레트 -> 프리미티브-Spacer : HPBar위 아래에 하나씩 배치 

 

(언리얼 에디터-UI_HPBar) HPBar-Spacer -> 디테일-슬롯-Size-채우기 : "40"

(언리얼 에디터-UI_HPBar) HPBar-Spacer -> 디테일-슬롯-Size-채우기 : "40"

// 퍼센트로 지정. 

 

(언리얼 에디터-BPMinion) HPBarComponent : 위치 조절

(언리얼 에디터-BPMinionRanger) HPBarComponent : 위치 조절

 

(언리얼 에디터-BPMinion) HPBarComponent -> 디테일-User Interface-Draw Size : X : "100" Y : "30"

(언리얼 에디터-BPMinionRanger) HPBarComponent -> 디테일-User Interface-Draw Size : X : "100" Y : "30"

 

(C++-UIHPBar.h)

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

#pragma once

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

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

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
    class UProgressBar* HPBar;
	
protected:
    virtual void NativeConstruct();
    virtual void NativeTick(const FGeometry& MyGeometry, float InDeltaTime);

public:
    UFUNCTION(BlueprintCallable)
    void SetHP(float fPercent);
    
};

(C++-UIHPBar.cpp)

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


#include "UIHPBar.h"
#include "Components/ProgressBar.h"

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

    HPBar = Cast<UProgressBar>(GetWidgetFromName(TEXT("HPBar")));
}

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

void UUIHPBar::SetHP(float fPercent)
{
    if (IsValid(HPBar))
        HPBar->SetPercent(fPercent);
}

(C++-Monster.h)

...
UCLASS()
class UE7PROJECT_API AMonster : public ACharacter
{
    GENERATED_BODY()
    
public:
    // Sets default values for this character's properties
    AMonster();

protected:
    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    ASpawnPoint* SpawnPoint;
    
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    class UWidgetComponent* HPBarComponent;
    
    class UUIHPBar* HPBarWidget;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    float fTraceRange;
    
    ...

(C++-Monster.cpp)

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


#include "Monster.h"
#include "UE7GameInstance.h"
#include "MonsterAIController.h"
#include "BehaviorTree/BehaviorTreeComponent.h"
#include "Components/WidgetComponent.h"
#include "UIHPBar.h"

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

    SpawnPoint = nullptr;
    bAttack = false;

    GetCapsuleComponent()->SetCollisionProfileName(TEXT("Monster"));
    
    GetMesh()->SetReceivesDecals(false);

    fTraceRange = 1000.f;
    fAttackDist = 200.f;
    iMovePoint = 0;
    iMovePointDir = 1;

    HPBarComponent = CreateDefaultSubobject<UWidgetComponent>(TEXT("HPBar"));

    HPBarComponent->SetupAttachment(GetMesh());

    HPBarComponent->SetWidgetSpace(EWidgetSpace::Screen);
    HPBarComponent->SetRelativeLocation(FVector(0.f, 0.f, 100.f));

    // HPBar Widget 불러옴. 
    static ConstructorHelpers::FClassFinder<UUserWidget> HPBarWidgetClass(TEXT("WidgetBlueprint'/Game/UI/UI_HPBar.UI_HPBar_C'"));

    if (HPBarWidgetClass.Succeeded())
        HPBarComponent->SetWidgetClass(HPBarWidgetClass.Class);

}

void AMonster::AddPatrolPoint(APatrolPoint* point)
{
    PatrolPointArray.Add(point);
}

// Called when the game starts or when spawned
void AMonster::BeginPlay()
{
    Super::BeginPlay();
	
    UUE7GameInstance* GameInst = GetGameInstance<UUE7GameInstance>();

    const FMonsterInfo* pMonsterInfo = GameInst->FindMonsterInfo(MonsterName);

    if (pMonsterInfo)
    {
        MonsterState.fAttack = pMonsterInfo->Attack;
        MonsterState.fArmor = pMonsterInfo->Armor;
        MonsterState.iHP = pMonsterInfo->HP;
        MonsterState.iHPMax = pMonsterInfo->HPMax;
        MonsterState.iMP = pMonsterInfo->MP;
        MonsterState.iMPMax = pMonsterInfo->iMPMax;
        fTraceRange = pMonsterInfo->TraceRange;
        fAttackDist = pMonsterInfo->AttackRange;
    }

    HPBarWidget = Cast<UUIHPBar>(HPBarComponent->GetUserWidgetObject());

    if (IsValid(HPBarWidget))
        HPBarWidget->SetHP(MonsterState.iHP / (float)MonsterState.iHPMax);
}

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

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

float AMonster::TakeDamage(float DamageAmount, FDamageEvent const& DamageEvent, AController* EventInstigator, AActor* DamageCauser)
{
    float fDamage = Super::TakeDamage(DamageAmount, DamageEvent, EventInstigator, DamageCauser);

    MonsterState.iHP -= (int32)fDamage;

    if (MonsterState.iHP <= 0)
    {
        MonsterState.iHP = 0;

        GetCapsuleComponent()->SetCollisionEnabled(ECollisionEnabled::NoCollision);

        ChangeAnim(EMonsterAnim::Death);

        AMonsterAIController* MonsterController = GetController<AMonsterAIController>();

        if (IsValid(MonsterController))
        {
            UBehaviorTreeComponent* BT = Cast<UBehaviorTreeComponent>(MonsterController->GetBrainComponent());
        
            if (IsValid(BT))
                BT->StopTree();
        }
    }

    if (IsValid(HPBarWidget))
        HPBarWidget->SetHP(MonsterState.iHP / (float)MonsterState.iHPMax);

    return fDamage;
}
...

 

 

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

[Unreal/정리] 캐릭터 선택  (0) 2020.11.09
[Unreal/정리] 시작 화면  (0) 2020.11.05
[Unreal/정리] 몬스터 상태 정보  (0) 2020.11.03
[Unreal/정리] Patrol  (0) 2020.11.02
[Unreal/정리] 행동트리  (0) 2020.10.26

댓글