diff --git a/Content/Blueprints/BP_ZombieCharacter.uasset b/Content/Blueprints/BP_ZombieCharacter.uasset index 0e6d14b..1496ef7 100644 --- a/Content/Blueprints/BP_ZombieCharacter.uasset +++ b/Content/Blueprints/BP_ZombieCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:77b8a3d480b401da5564414c3a68d87e0ce6ea52c820d275b3b10131a96c4d22 -size 28984 +oid sha256:30dd531abe7ed074897e22da99df2fb0581802f31d12447faf9677628d9ee445 +size 28698 diff --git a/Content/HUD/BP_ZOmbiePlayerHUD.uasset b/Content/HUD/BP_ZOmbiePlayerHUD.uasset new file mode 100644 index 0000000..085b1ca --- /dev/null +++ b/Content/HUD/BP_ZOmbiePlayerHUD.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f596ecd07c4b5bb9548d807ebe9496c20c533fd41f1371a465e5f500440d49d +size 44005 diff --git a/Content/Images/life_green.uasset b/Content/Images/life_green.uasset new file mode 100644 index 0000000..c9fbaf6 --- /dev/null +++ b/Content/Images/life_green.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39bd91a3aee79e4a34d10401d00ae0b18fe224ef22ecc225e3178ab5da6c1dec +size 10209 diff --git a/Content/Images/life_grey.uasset b/Content/Images/life_grey.uasset new file mode 100644 index 0000000..c58e9d4 --- /dev/null +++ b/Content/Images/life_grey.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0098b96eebb2261cc036f37ca4f493f879a70ca033069f2830c0ce668e1b439 +size 9855 diff --git a/EndlessZombie.uproject b/EndlessZombie.uproject index bed7922..1c523e8 100644 --- a/EndlessZombie.uproject +++ b/EndlessZombie.uproject @@ -9,7 +9,8 @@ "Type": "Runtime", "LoadingPhase": "Default", "AdditionalDependencies": [ - "Engine" + "Engine", + "UMG" ] } ], diff --git a/Source/EndlessZombie/EndlessZombie.Build.cs b/Source/EndlessZombie/EndlessZombie.Build.cs index e82e287..b8373b1 100644 --- a/Source/EndlessZombie/EndlessZombie.Build.cs +++ b/Source/EndlessZombie/EndlessZombie.Build.cs @@ -4,10 +4,18 @@ using UnrealBuildTool; public class EndlessZombie : ModuleRules { - public EndlessZombie(ReadOnlyTargetRules Target) : base(Target) - { - PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + public EndlessZombie(ReadOnlyTargetRules Target) : base(Target) + { + PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; - PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "HeadMountedDisplay", "EnhancedInput" }); - } + PublicDependencyModuleNames.AddRange(new string[] { + "Core", + "CoreUObject", + "Engine", + "InputCore", + "HeadMountedDisplay", + "EnhancedInput", + "UMG" + }); + } } diff --git a/Source/EndlessZombie/EndlessZombieGameMode.h b/Source/EndlessZombie/EndlessZombieGameMode.h index 3297eb4..18e28cf 100644 --- a/Source/EndlessZombie/EndlessZombieGameMode.h +++ b/Source/EndlessZombie/EndlessZombieGameMode.h @@ -15,6 +15,9 @@ public: AEndlessZombieGameMode(); void RestartLevel(); + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Life") + int iPlayerLife = 3; }; diff --git a/Source/EndlessZombie/ZombieCharacter.cpp b/Source/EndlessZombie/ZombieCharacter.cpp index 4be5c58..f595dfd 100644 --- a/Source/EndlessZombie/ZombieCharacter.cpp +++ b/Source/EndlessZombie/ZombieCharacter.cpp @@ -1,6 +1,8 @@ // Copyright Jorge Kuijper. All Rights Reserved. #include "ZombieCharacter.h" +#include "ZombiePlayerHUD.h" +#include "Blueprint/UserWidget.h" #include "EndlessZombieGameMode.h" #include "Camera/CameraComponent.h" #include "EnhancedInputComponent.h" @@ -52,6 +54,10 @@ AZombieCharacter::AZombieCharacter() FollowCamera->SetWorldRotation(FQuat(FRotator(-15.f, 0.f, 0.f))); bReadyState = true; + + // HUD + ZombiePlayerHUDClass = nullptr; + ZombieHUD = nullptr; } // Called when the game starts or when spawned @@ -65,6 +71,12 @@ void AZombieCharacter::BeginPlay() { Subsystem->AddMappingContext(DefaultMappingContext, 0); } + if (ZombiePlayerHUDClass) + { + ZombieHUD = CreateWidget(PlayerController, ZombiePlayerHUDClass); + if (ZombieHUD) + ZombieHUD->AddToPlayerScreen(); + } } DynamicFlashMaterial = GetMesh()->CreateDynamicMaterialInstance(0); @@ -81,6 +93,17 @@ void AZombieCharacter::BeginPlay() } } +void AZombieCharacter::EndPlay(const EEndPlayReason::Type EndPlayReason) +{ + if (ZombieHUD) + { + ZombieHUD->RemoveFromParent(); + ZombieHUD = nullptr; + } + + Super::EndPlay(EndPlayReason); +} + // Called every frame void AZombieCharacter::Tick(float DeltaTime) { @@ -185,14 +208,20 @@ void AZombieCharacter::Die() void AZombieCharacter::ObstacleCollision() { - iPlayerLife--; - if (iPlayerLife > 0) + AEndlessZombieGameMode* CurrentGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); + if (CurrentGameMode) { - PlayFlashEffect(); - } - else - { - Die(); + CurrentGameMode->iPlayerLife--; + if (CurrentGameMode->iPlayerLife > 0) + { + PlayFlashEffect(); + ZombieHUD->ModifyLifeCounter(); + } + else + { + ZombieHUD->ModifyLifeCounter(); + Die(); + } } } @@ -212,7 +241,7 @@ void AZombieCharacter::ControlFlashing() { fTimelineValue = FlashTimeline.GetPlaybackPosition(); float fFlashCurve = FlashCurve->GetFloatValue(fTimelineValue); - + float alpha = FMath::Lerp(0.f, fGlobalMultiplier, fFlashCurve); DynamicFlashMaterial->SetScalarParameterValue("FlashMultiplier", alpha); } diff --git a/Source/EndlessZombie/ZombieCharacter.h b/Source/EndlessZombie/ZombieCharacter.h index 35f846b..ea72fa9 100644 --- a/Source/EndlessZombie/ZombieCharacter.h +++ b/Source/EndlessZombie/ZombieCharacter.h @@ -48,6 +48,8 @@ protected: // Called when the game starts or when spawned virtual void BeginPlay() override; + virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + // APawn interface virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override; @@ -69,9 +71,7 @@ public: UPROPERTY(EditAnywhere, Category = "Movement") float fBaseSpeed = 5.f; UPROPERTY(EditAnywhere, Category = "Movement") - float fAcceleration = .001f; - UPROPERTY(EditAnywhere, Category = "Life") - int iPlayerLife = 3; + float fAcceleration = .01f; bool bCanTurn = false; FRotator rDesireRotation = FRotator(0.f, 0.f, 0.f); @@ -95,6 +95,11 @@ public: float fTimelineValue; FTimeline FlashTimeline; + UPROPERTY(EditAnywhere, Category = "HUD") + TSubclassOf ZombiePlayerHUDClass; + UPROPERTY() + class UZombiePlayerHUD* ZombieHUD; + private: void MoveForwardConstant(float DeltaTime); diff --git a/Source/EndlessZombie/ZombiePlayerHUD.cpp b/Source/EndlessZombie/ZombiePlayerHUD.cpp new file mode 100644 index 0000000..6c9f125 --- /dev/null +++ b/Source/EndlessZombie/ZombiePlayerHUD.cpp @@ -0,0 +1,57 @@ +// Copyright Jorge Kuijper. All Rights Reserved. + + +#include "ZombiePlayerHUD.h" +#include "Components/Image.h" +#include "Components/TextBlock.h" +#include "EndlessZombieGameMode.h" +#include "Kismet/GameplayStatics.h" + +void UZombiePlayerHUD::NativeConstruct() +{ + Super::NativeConstruct(); + + // ItemTitle can be nullptr if we haven't created it in the + // Blueprint subclass + if (TextLife) + { + TextLife->SetText(FText::FromString(TEXT("Lifes: "))); + } + + if (LifeImg01) + { + LifeImg01->SetBrushFromTexture(LifeGreenTexture); + } + + CurrentGameMode = Cast(UGameplayStatics::GetGameMode(GetWorld())); +} + +void UZombiePlayerHUD::ModifyLifeCounter() +{ + if (CurrentGameMode) + { + switch (CurrentGameMode->iPlayerLife) + { + case 2: + EmptyLife(LifeImg03); + break; + case 1: + EmptyLife(LifeImg02); + break; + case 0: + EmptyLife(LifeImg01); + break; + default: + break; + } + } + +} + +void UZombiePlayerHUD::EmptyLife(UImage* LifeImg) +{ + if ((LifeImg) && (LifeGreyTexture)) + { + LifeImg->SetBrushFromTexture(LifeGreyTexture); + } +} diff --git a/Source/EndlessZombie/ZombiePlayerHUD.h b/Source/EndlessZombie/ZombiePlayerHUD.h new file mode 100644 index 0000000..610d173 --- /dev/null +++ b/Source/EndlessZombie/ZombiePlayerHUD.h @@ -0,0 +1,43 @@ +// Copyright Jorge Kuijper. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Blueprint/UserWidget.h" +#include "ZombiePlayerHUD.generated.h" + +class UTextBlock; +class UImage; +class AEndlessZombieGameMode; +/** + * + */ +UCLASS() +class ENDLESSZOMBIE_API UZombiePlayerHUD : public UUserWidget +{ + GENERATED_BODY() + +protected: + virtual void NativeConstruct() override; + +public: + UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) + UTextBlock* TextLife; + UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) + UImage* LifeImg01; + UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) + UImage* LifeImg02; + UPROPERTY(BlueprintReadWrite, meta = (BindWidget)) + UImage* LifeImg03; + UPROPERTY(EditAnywhere) + UTexture2D* LifeGreenTexture; + UPROPERTY(EditAnywhere) + UTexture2D* LifeGreyTexture; + + AEndlessZombieGameMode* CurrentGameMode; + + void ModifyLifeCounter(); + +private: + void EmptyLife(UImage* LifeImg); +};