From 8c01cab7c8f4233afd050b2e05758897c4f1dbcf Mon Sep 17 00:00:00 2001 From: Oleg Petruny Date: Fri, 22 Nov 2024 19:47:34 +0100 Subject: [PATCH] finalization --- .../Lost_Edge/Config/DefaultEngine.ini | 6 +- .../AgeOfWar/BP_Minigame_AgeOfWar.uasset | 4 +- .../AgeOfWar/UI_Minigame_AgeOfWar.uasset | 4 +- .../BP_Minigame_AgeOfWarUnit_Base.uasset | 4 +- ...BP_Minigame_AgeOfWarUnit_FirstMelee.uasset | 4 +- ...BP_Minigame_AgeOfWarUnit_FirstRange.uasset | 4 +- .../BP_Minigame_AgeOfWarUnit_FirstTank.uasset | 4 +- .../Lost_Edge/Content/Levels/Test/L_Test.umap | 4 +- .../Lost_Edge/Private/CommonFunctions.cpp | 12 +++ .../Lost_Edge/Private/CommonFunctions.h | 2 + .../Minigame/AgeOfWar/AgeOfWarManager.cpp | 17 +++++ .../Minigame/AgeOfWar/AgeOfWarManager.h | 2 + .../Minigame/AgeOfWar/AgeOfWarUnit.cpp | 73 ++++++++++++++++--- .../Private/Minigame/AgeOfWar/AgeOfWarUnit.h | 22 +++++- 14 files changed, 134 insertions(+), 28 deletions(-) diff --git a/UnrealProject/Lost_Edge/Config/DefaultEngine.ini b/UnrealProject/Lost_Edge/Config/DefaultEngine.ini index 369b66a..c9b460d 100644 --- a/UnrealProject/Lost_Edge/Config/DefaultEngine.ini +++ b/UnrealProject/Lost_Edge/Config/DefaultEngine.ini @@ -139,7 +139,8 @@ ManualIPAddress= +Profiles=(Name="Vehicle",CollisionEnabled=QueryAndPhysics,bCanModify=False,ObjectTypeName="Vehicle",CustomResponses=,HelpMessage="Vehicle object that blocks Vehicle, WorldStatic, and WorldDynamic. All other channels will be set to default.") +Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ") +Profiles=(Name="Interactable",CollisionEnabled=QueryAndPhysics,bCanModify=True,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="Interactable")),HelpMessage="WorldDynamic objects derived from AInteractable.") -+Profiles=(Name="AgeOfWarUnit",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="Vehicle",CustomResponses=((Channel="WorldStatic",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore)),HelpMessage="Minigame object") ++Profiles=(Name="AgeOfWarUnitPlayer",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="Vehicle",CustomResponses=((Channel="WorldStatic",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Vehicle",Response=ECR_Ignore),(Channel="Interactable")),HelpMessage="Minigame object") ++Profiles=(Name="AgeOfWarUnitComputer",CollisionEnabled=QueryOnly,bCanModify=True,ObjectTypeName="Destructible",CustomResponses=((Channel="WorldStatic",Response=ECR_Ignore),(Channel="WorldDynamic",Response=ECR_Ignore),(Channel="Pawn",Response=ECR_Ignore),(Channel="Visibility",Response=ECR_Ignore),(Channel="Camera",Response=ECR_Ignore),(Channel="PhysicsBody",Response=ECR_Ignore),(Channel="Destructible",Response=ECR_Ignore),(Channel="Interactable")),HelpMessage="Minigame object") +DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="Interactable") -ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall") -ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn") @@ -151,6 +152,9 @@ ManualIPAddress= +ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic") +ProfileRedirects=(OldName="SkeletalMeshActor",NewName="PhysicsActor") +ProfileRedirects=(OldName="InvisibleActor",NewName="InvisibleWallDynamic") ++ProfileRedirects=(OldName="AgeOfWarUnitComputer",NewName="AgeOfWarUnitPlayerZone") ++ProfileRedirects=(OldName="AgeOfWarUnit",NewName="AgeOfWarUnitPlayer") ++ProfileRedirects=(OldName="AgeOfWarUnitPlayerZone",NewName="AgeOfWarUnitComputer") -CollisionChannelRedirects=(OldName="Static",NewName="WorldStatic") -CollisionChannelRedirects=(OldName="Dynamic",NewName="WorldDynamic") -CollisionChannelRedirects=(OldName="VehicleMovement",NewName="Vehicle") diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/BP_Minigame_AgeOfWar.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/BP_Minigame_AgeOfWar.uasset index 35f9a4f..8ae7155 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/BP_Minigame_AgeOfWar.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/BP_Minigame_AgeOfWar.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eb79e9917fe826eb430ee33c9f2f3899bab8a193eb230ce24017fb13c4179e7f -size 366061 +oid sha256:5e9165dea307bfecba98443cb3889799bc4f656fc85e226377392c4fd839cea0 +size 496980 diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/UI_Minigame_AgeOfWar.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/UI_Minigame_AgeOfWar.uasset index 71b6ab2..08c3412 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/UI_Minigame_AgeOfWar.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/UI_Minigame_AgeOfWar.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:48d61e4adb9f190548560d1e42f2d07c60564a988ba877f70e528c204e544709 -size 181823 +oid sha256:bd73e8683b46355038b4921e52202d05b44eebfd571f83a1feb38656267e960d +size 212213 diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_Base.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_Base.uasset index d0c20a2..19d16fb 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_Base.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_Base.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:12a1a84218555e73e3f9ef1f3db30bf3e1ca2b427a041839128f111e97d80263 -size 23941 +oid sha256:9be205b5bf17894060db9e19a165ef429b0a0a01286c0e166db769dc45376b9b +size 42295 diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstMelee.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstMelee.uasset index aaadec9..38b45f8 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstMelee.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstMelee.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:905f95b9ba7239185a27a95f0dc44c394705c7ae7c1edf38274a29cb8d5eeed7 -size 23343 +oid sha256:a6f29c6ad1559cd22960b40f851bb7873a0e923695c2fab06d02db94d7900e3a +size 23540 diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstRange.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstRange.uasset index 1766f2a..777ac8b 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstRange.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstRange.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:685d868675c82a533270e268390749c68bd14f8d1d08059ee090a24748e2998d -size 26335 +oid sha256:89f21d2809ef7f853839bd572a95c180b5c2668a3243197f9a74bcadc94d6d5d +size 25523 diff --git a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstTank.uasset b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstTank.uasset index 8e12740..06efab6 100644 --- a/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstTank.uasset +++ b/UnrealProject/Lost_Edge/Content/Blueprints/Minigames/AgeOfWar/Units/BP_Minigame_AgeOfWarUnit_FirstTank.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8202a38d55de0cc6f348780d036e2c08fcc2d0860e28ce6649346ec71989f49a -size 23930 +oid sha256:6a92537e1f82b2e1745b363b518751a61f9efefb223159701950f1f835e1b469 +size 23008 diff --git a/UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap b/UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap index 435c279..33667b3 100644 --- a/UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap +++ b/UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdd549e2cfccd08d1cf7a9347d806405311dbd11d371bb8677428ef5aba7f9ed -size 2265093 +oid sha256:6d6d75c266fe70db878a1a4c8ad461c4f31dd3c92662074f083295eff4bf0d13 +size 2265074 diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.cpp b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.cpp index 6248b2e..3a5e4fa 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.cpp +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.cpp @@ -39,6 +39,18 @@ void UCommonFunctions::DestroyActorRecursively(AActor* actor) actor->Destroy(); } +TArray UCommonFunctions::GetRandomIntArray(int32 size, int32 min, int32 max) +{ + if(size <= 0) + return {}; + + TArray arr; + arr.Reserve(size); + for(int32 i = 0; i < size; ++i) + arr.Add(FMath::RandRange(min, max)); + return arr; +} + ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj) diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h index 903cead..b5c9b17 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/CommonFunctions.h @@ -21,6 +21,8 @@ public: UFUNCTION(BlueprintCallable, Category = Actor) static void DestroyActorRecursively(class AActor* actor); + UFUNCTION(BlueprintPure) + static TArray GetRandomIntArray(int32 size = 16, int32 min = 0, int32 max = 16); UFUNCTION(BlueprintCallable, Category = Level) diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.cpp b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.cpp index 7f566a9..659903b 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.cpp +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.cpp @@ -15,6 +15,11 @@ TMap AAgeOfWarManager::unitStats = {}; const FAgeOfWarUnitStats& AAgeOfWarManager::UnitGetStats(TSubclassOf unitClass) { check(unitStats.Contains(*unitClass)); + //if(!unitStats.Contains(*unitClass)) + //{ + // static FAgeOfWarUnitStats empty; + // return empty; + //} return unitStats[unitClass]; } @@ -52,6 +57,10 @@ void AAgeOfWarManager::Start(APlayerBase* playerPawn, FMinigameEndCallback deleg void AAgeOfWarManager::End() { + for(auto& unit : spawnedUnits) + unit->Destroy(); + spawnedUnits.Empty(); + unitStats.Empty(); player->ReturnPlayerView(); @@ -60,6 +69,12 @@ void AAgeOfWarManager::End() AMinigame::End(); } +void AAgeOfWarManager::UnitKill(AAgeOfWarUnit* unit) +{ + OnUnitKill(unit); + spawnedUnits.Remove(unit); +} + void AAgeOfWarManager::AddUnitStats(TSubclassOf unitClass, FAgeOfWarUnitStats stats) { unitStats.Add(unitClass, stats); @@ -77,4 +92,6 @@ void AAgeOfWarManager::SpawnUnit(TSubclassOf unitClass, FTransfor auto unit = GetWorld()->SpawnActor(*unitClass, transform, spawnParams); unit->team = computer ? UnitTeam::AI : UnitTeam::Player; unit->manager = this; + unit->UpdateStats(); + spawnedUnits.Add(unit); } diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.h b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.h index 099e729..dbcdcb9 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.h +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarManager.h @@ -19,6 +19,7 @@ public: virtual void Start(class APlayerBase* playerPawn, FMinigameEndCallback delegate) override; virtual void End() override; + void UnitKill(class AAgeOfWarUnit* unit); UFUNCTION(BlueprintImplementableEvent) void OnUnitKill(class AAgeOfWarUnit* unit); @@ -38,4 +39,5 @@ protected: UPROPERTY(EditAnywhere) class UCameraComponent* camera; + TSet spawnedUnits; }; diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.cpp b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.cpp index efb92fb..88a4826 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.cpp +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.cpp @@ -8,6 +8,13 @@ #include "AgeOfWarManager.h" #include +namespace +{ + constexpr auto PlayerCollision = TEXT("AgeOfWarUnitPlayer"); + constexpr auto ComputerCollision = TEXT("AgeOfWarUnitComputer"); + constexpr auto TagNoAuto = TEXT("NoAuto"); +} + const FAgeOfWarUnitStats& AAgeOfWarUnit::GetStats() { if(!stats) @@ -19,6 +26,25 @@ const FAgeOfWarUnitStats& AAgeOfWarUnit::GetStats() void AAgeOfWarUnit::UpdateStats() { health = GetStats().health; + attackStartRange = GetStats().attackStartRange; + + switch(team) + { + case UnitTeam::AI: + root->SetCollisionProfileName(ComputerCollision); + allyblocker->SetCollisionProfileName(PlayerCollision); + break; + case UnitTeam::Player: + root->SetCollisionProfileName(PlayerCollision); + allyblocker->SetCollisionProfileName(ComputerCollision); + break; + default: + break; + } + allyblocker->SetBoxExtent(root->GetUnscaledBoxExtent(), false); + allyblocker->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + OnUpdateStats(); } void AAgeOfWarUnit::BeginPlay() @@ -29,6 +55,8 @@ void AAgeOfWarUnit::BeginPlay() } Super::BeginPlay(); + + world = GetWorld(); } void AAgeOfWarUnit::EndPlay(const EEndPlayReason::Type EndPlayReason) @@ -38,10 +66,12 @@ void AAgeOfWarUnit::EndPlay(const EEndPlayReason::Type EndPlayReason) AAgeOfWarUnit::AAgeOfWarUnit() { - //auto root = CreateDefaultSubobject(TEXT("Scene")); - // - //collision = CreateDefaultSubobject(TEXT("Collision")); - //collision->SetCollisionProfileName(TEXT("AgeOfWarUnit")); + root = CreateDefaultSubobject(TEXT("Collision")); + allyblocker = CreateDefaultSubobject(TEXT("AllyBlocker")); + allyblocker->SetupAttachment(root); + traceStart = CreateDefaultSubobject(TEXT("TraceStart")); + traceStart->SetupAttachment(root); + traceStart->AddRelativeLocation(FVector(0, 0, 200)); PrimaryActorTick.bCanEverTick = true; PrimaryActorTick.bStartWithTickEnabled = true; @@ -54,10 +84,26 @@ void AAgeOfWarUnit::Tick(float deltaTime) if(!manager || GetStats().moveSpeed <= 0) return; - // move unit forward + // try move + FHitResult moveHit; auto moveStep = GetActorForwardVector() * GetStats().moveSpeed; + this->AddActorWorldOffset(moveStep, true, &moveHit, ETeleportType::None); + if(moveHit.bBlockingHit) + allyblocker->SetCollisionEnabled(ECollisionEnabled::QueryOnly); + else + allyblocker->SetCollisionEnabled(ECollisionEnabled::NoCollision); + + // look for units forward FHitResult hit; - this->AddActorWorldOffset(moveStep, true, &hit, ETeleportType::None); + auto startLocation = traceStart->GetComponentLocation(); + auto endLocation = startLocation + (GetActorRotation().Vector() * attackStartRange * (moveHit.bBlockingHit ? 5 : 1)); + world->LineTraceSingleByChannel( + hit, + startLocation, + endLocation, + ECollisionChannel::ECC_GameTraceChannel1 + ); + DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, deltaTime * 10, 0, 4.0f); // check if blocked if(!hit.bBlockingHit) @@ -71,7 +117,7 @@ void AAgeOfWarUnit::Tick(float deltaTime) } // iterate to attackable unit - for(int i = 1; forwardUnit->team == team && i < GetStats().attackDistance; i += forwardUnit->GetStats().unitSize) + for(int i = 1; forwardUnit->team == team && i < GetStats().attackUnitDistance; i += forwardUnit->GetStats().unitSize) forwardUnit = forwardUnit->forwardUnit; // if forward unit is in the same team skip attack @@ -89,15 +135,24 @@ void AAgeOfWarUnit::Tick(float deltaTime) void AAgeOfWarUnit::Damage(const int32 damage) { - GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Yellow, FString::Printf(TEXT("Damage %d taken by %s"), damage, *GetClass()->GetName())); + if(killed) + return; + + GEngine->AddOnScreenDebugMessage((int32)GetClass()->GetUniqueID(), 5.0f, FColor::Yellow, FString::Printf(TEXT("%d"), health)); health -= damage; if(health > 0) return; + killed = true; + if(IsValid(manager)) - manager->OnUnitKill(this); + { + manager->UnitKill(this); + } else + { Destroy(); + } } diff --git a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.h b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.h index d1652d5..1184f8e 100644 --- a/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.h +++ b/UnrealProject/Lost_Edge/Source/Lost_Edge/Private/Minigame/AgeOfWar/AgeOfWarUnit.h @@ -27,7 +27,10 @@ struct FAgeOfWarUnitStats int32 attackDamage = 1; UPROPERTY(EditAnywhere, BlueprintReadWrite) - int32 attackDistance = 1; + int32 attackUnitDistance = 1; + + UPROPERTY(EditAnywhere, BlueprintReadWrite) + float attackStartRange = 100; UPROPERTY(EditAnywhere, BlueprintReadWrite) float attackRate = 1.0f; @@ -69,17 +72,28 @@ protected: virtual void BeginPlay() override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; + UFUNCTION(BlueprintImplementableEvent) + void OnUpdateStats(); + void Damage(const int32 damage); AAgeOfWarUnit* forwardUnit = nullptr; -private: - UPROPERTY(EditAnywhere) - class UBoxComponent* collision; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + class UBoxComponent* root; + UPROPERTY(EditAnywhere, BlueprintReadWrite) + class UBoxComponent* allyblocker; + UPROPERTY(EditAnywhere) + class USceneComponent* traceStart; + +private: int32 health; + float attackStartRange; FTimerHandle attackTimer; double lastAttackTimestamp = 0; + UWorld* world; + bool killed = false; };