From 4d10d9cb32a936990642ff5798ab9444cd7c9b69 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 15 Jan 2022 23:41:56 -0500 Subject: [PATCH] Setup game mode so characters are spawned automatically rather than placing them in the world Setup game mode so characters are spawned automatically rather than placing them in the world --- KOFForever/Config/DefaultEngine.ini | 2 +- .../Core/BP_MainPlayerController.uasset | 4 +- .../Content/Debug/BP_DebugGameMode.uasset | 3 + KOFForever/Content/Maps/DebugStage.umap | 3 + KOFForever/Content/Maps/TrainingStage.umap | 3 + KOFForever/KOFForever.uproject | 3 +- .../Private/Camera/KOFDefaultCamera.cpp | 78 ++++++++++++++++--- .../Private/Character/KOFBaseCharacter.cpp | 6 +- .../Private/GameModes/KOFDefaultGameMode.cpp | 64 +++++++++++++++ .../KOFForever/Private/GameModes/KOFTeam.cpp | 23 ++++++ .../Public/Camera/KOFDefaultCamera.h | 13 ++-- .../Public/GameModes/KOFDefaultGameMode.h | 62 +++++++++++++++ .../KOFForever/Public/GameModes/KOFTeam.h | 38 +++++++++ 13 files changed, 278 insertions(+), 24 deletions(-) create mode 100644 KOFForever/Content/Debug/BP_DebugGameMode.uasset create mode 100644 KOFForever/Content/Maps/DebugStage.umap create mode 100644 KOFForever/Content/Maps/TrainingStage.umap create mode 100644 KOFForever/Source/KOFForever/Private/GameModes/KOFDefaultGameMode.cpp create mode 100644 KOFForever/Source/KOFForever/Private/GameModes/KOFTeam.cpp create mode 100644 KOFForever/Source/KOFForever/Public/GameModes/KOFDefaultGameMode.h create mode 100644 KOFForever/Source/KOFForever/Public/GameModes/KOFTeam.h diff --git a/KOFForever/Config/DefaultEngine.ini b/KOFForever/Config/DefaultEngine.ini index d505c84..32eb7ba 100644 --- a/KOFForever/Config/DefaultEngine.ini +++ b/KOFForever/Config/DefaultEngine.ini @@ -1,7 +1,7 @@ [/Script/EngineSettings.GameMapsSettings] -EditorStartupMap=/Game/Maps/TestMap.TestMap +EditorStartupMap=/Game/Maps/DebugStage.DebugStage LocalMapOptions= TransitionMap= bUseSplitscreen=True diff --git a/KOFForever/Content/Core/BP_MainPlayerController.uasset b/KOFForever/Content/Core/BP_MainPlayerController.uasset index 4333401..6081e77 100644 --- a/KOFForever/Content/Core/BP_MainPlayerController.uasset +++ b/KOFForever/Content/Core/BP_MainPlayerController.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f1164cabcfba95e36b36315217ddb67fcabd1309beae3fa94954a0119705bd8c -size 32353 +oid sha256:8b9c8e5425cb6b9cb031b489c49e5f4eb921c202d4ffdc0f1ac7d887531b4fde +size 32282 diff --git a/KOFForever/Content/Debug/BP_DebugGameMode.uasset b/KOFForever/Content/Debug/BP_DebugGameMode.uasset new file mode 100644 index 0000000..20b1415 --- /dev/null +++ b/KOFForever/Content/Debug/BP_DebugGameMode.uasset @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7770532361694fba926359a02f4874cec86d186ebf88b22a2e308c29d4bf8f17 +size 18779 diff --git a/KOFForever/Content/Maps/DebugStage.umap b/KOFForever/Content/Maps/DebugStage.umap new file mode 100644 index 0000000..9fa925c --- /dev/null +++ b/KOFForever/Content/Maps/DebugStage.umap @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0734c34f22596584ab16ae499c6df6869ce893efc067598c4e80b8a451b6677d +size 8531398 diff --git a/KOFForever/Content/Maps/TrainingStage.umap b/KOFForever/Content/Maps/TrainingStage.umap new file mode 100644 index 0000000..c61a29a --- /dev/null +++ b/KOFForever/Content/Maps/TrainingStage.umap @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33c22cc90246a4c63062ba2f5906b7ceff8f0bbbfa78189551a2811f3e5e2055 +size 8536856 diff --git a/KOFForever/KOFForever.uproject b/KOFForever/KOFForever.uproject index f41e767..0451eda 100644 --- a/KOFForever/KOFForever.uproject +++ b/KOFForever/KOFForever.uproject @@ -10,7 +10,8 @@ "LoadingPhase": "Default", "AdditionalDependencies": [ "Paper2D", - "Engine" + "Engine", + "CoreUObject" ] } ] diff --git a/KOFForever/Source/KOFForever/Private/Camera/KOFDefaultCamera.cpp b/KOFForever/Source/KOFForever/Private/Camera/KOFDefaultCamera.cpp index f2af1db..16ae7c2 100644 --- a/KOFForever/Source/KOFForever/Private/Camera/KOFDefaultCamera.cpp +++ b/KOFForever/Source/KOFForever/Private/Camera/KOFDefaultCamera.cpp @@ -5,6 +5,8 @@ #include "DrawDebugHelpers.h" #include "Camera/CameraComponent.h" +#include "Character/KOFBaseCharacter.h" +#include "GameModes/KOFDefaultGameMode.h" AKOFDefaultCamera::AKOFDefaultCamera() { @@ -16,21 +18,79 @@ AKOFDefaultCamera::AKOFDefaultCamera() HeightOffset = 60.0f; ZAveragingFactor = 2.0f; + + MovementYDistanceThreshold = 500.0f; } void AKOFDefaultCamera::Tick(float DeltaSeconds) { Super::Tick(DeltaSeconds); - check(P1); - check(P2); + // NOTE(kevin): This will only return the game mode if we are the server. Since this game is local only we should always + // be both server and client + AKOFDefaultGameMode* GameMode = Cast(GetWorld()->GetAuthGameMode()); - FVector P1Loc = P1->GetActorLocation(); - FVector P2Loc = P2->GetActorLocation(); - FVector CameraLoc = GetActorLocation(); + if(GameMode) + { + AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter(); + AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter(); + + check(P1); + check(P2); - FVector MidPoint = FVector(CameraLoc.X, (P1Loc.Y + P2Loc.Y) / 2.0f, ((P1Loc.Z + P2Loc.Z) / ZAveragingFactor) + HeightOffset); - SetActorLocation(MidPoint); - - // set FOV + FVector P1Loc = P1->GetActorLocation(); + FVector P2Loc = P2->GetActorLocation(); + FVector CameraLoc = GetActorLocation(); + + FVector MidPoint = FVector(CameraLoc.X, (P1Loc.Y + P2Loc.Y) / 2.0f, ((P1Loc.Z + P2Loc.Z) / ZAveragingFactor) + HeightOffset); + SetActorLocation(MidPoint); + + // set FOV + } } + +void AKOFDefaultCamera::UpdateCamera() +{ + // NOTE(kevin): This will only return the game mode if we are the server. Since this game is local only we should always + // be both server and client + AKOFDefaultGameMode* GameMode = Cast(GetWorld()->GetAuthGameMode()); + + if(GameMode) + { + AKOFBaseCharacter* P1 = GameMode->GetP1CurrentCharacter(); + AKOFBaseCharacter* P2 = GameMode->GetP2CurrentCharacter(); + + FVector P1Loc = P1->GetActorLocation(); + FVector P2Loc = P2->GetActorLocation(); + FVector CameraLoc = GetActorLocation(); + + float HalfMoveYThreshold = MovementYDistanceThreshold / 2.0f; + + float YDistance = FMath::Abs(P1Loc.Y - P2Loc.Y); + + /** + * If one of the characters starts to move far enough to either side of the camera (determined by Movement Y distance threshold), + * then start pushing the camera in that same direction + */ + /* + if((P1Loc.Y < CameraLoc.Y - HalfMoveYThreshold || P2Loc.Y < CameraLoc.Y - HalfMoveYThreshold) || + (P1Loc.Y > CameraLoc.Y + HalfMoveYThreshold || P2Loc.Y > CameraLoc.Y + HalfMoveYThreshold)) + { + //FVector MidPoint = FVector(CameraLoc.X, (P1Loc.Y + P2Loc.Y) / 2.0f, ((P1Loc.Z + P2Loc.Z) / ZAveragingFactor) + HeightOffset); + FVector MidPoint = FVector(CameraLoc.X, (P1Loc.Y + P2Loc.Y) / 2.0f, CameraLoc.Z); + SetActorLocation(MidPoint); + } + */ + + + // leftest = MaxF(float32(Min(s.stage.p[0].startx, s.stage.p[1].startx))*s.stage.localscl,-(float32(s.gameWidth)/2)/s.cam.BaseScale()+s.screenleft) - ox + // rightest = MinF(float32(Max(s.stage.p[0].startx, s.stage.p[1].startx))*s.stage.localscl, (float32(s.gameWidth)/2)/s.cam.BaseScale()-s.screenright) - ox + + float MoveRightVal = P1Loc.Y > CameraLoc.Y + HalfMoveYThreshold ? P1Loc.Y - (CameraLoc.Y + HalfMoveYThreshold) : 0.0f; + float MoveLeftVal = P1Loc.Y < CameraLoc.Y - HalfMoveYThreshold ? P1Loc.Y - (CameraLoc.Y - HalfMoveYThreshold) : 0.0f; + + FVector NewLocation = FVector(CameraLoc.X, (CameraLoc.Y + MoveRightVal - MoveLeftVal), CameraLoc.Z); + } +} + + diff --git a/KOFForever/Source/KOFForever/Private/Character/KOFBaseCharacter.cpp b/KOFForever/Source/KOFForever/Private/Character/KOFBaseCharacter.cpp index b3d384a..000fc00 100644 --- a/KOFForever/Source/KOFForever/Private/Character/KOFBaseCharacter.cpp +++ b/KOFForever/Source/KOFForever/Private/Character/KOFBaseCharacter.cpp @@ -85,11 +85,11 @@ void AKOFBaseCharacter::UpdateAnimation() UPaperFlipbook* DesiredAnimation = IdleAnimation; if(PlayerSpeedSqr > 0.0f) { - if (TravelDirection < 0.0f) + if (TravelDirection > 0.0f) { DesiredAnimation = WalkFwdAnimation; } - else if (TravelDirection > 0.0f) + else if (TravelDirection < 0.0f) { DesiredAnimation = WalkBackAnimation; } @@ -152,7 +152,7 @@ void AKOFBaseCharacter::MoveRight(float Value) /*UpdateChar();*/ // Apply the input to the character motion - AddMovementInput(FVector(0.0f, -1.0f, 0.0f), Value); + AddMovementInput(FVector(0.0f, 1.0f, 0.0f), Value); } void AKOFBaseCharacter::UpdateCharacter() diff --git a/KOFForever/Source/KOFForever/Private/GameModes/KOFDefaultGameMode.cpp b/KOFForever/Source/KOFForever/Private/GameModes/KOFDefaultGameMode.cpp new file mode 100644 index 0000000..cb54cbd --- /dev/null +++ b/KOFForever/Source/KOFForever/Private/GameModes/KOFDefaultGameMode.cpp @@ -0,0 +1,64 @@ + + + +#include "GameModes/KOFDefaultGameMode.h" + +#include "Kismet/GameplayStatics.h" + +AKOFDefaultGameMode::AKOFDefaultGameMode() +{ + NumCharactersPerTeam = 3; + + MaxDistance = 700.0f; + StartY = 250.0f; +} + +void AKOFDefaultGameMode::InitTeams() +{ + for (TSubclassOf CharacterTemplate : P1TeamTemplate) + { + AKOFBaseCharacter* Temp = GetWorld()->SpawnActor(CharacterTemplate, FVector(0.0f, -StartY, 204.6241f), FRotator(0.0f, 90.0f, 0.0f)); + if(Temp) + { + P1Team.Add(Temp); + } + } + + for (TSubclassOf CharacterTemplate : P2TeamTemplate) + { + AKOFBaseCharacter* Temp = GetWorld()->SpawnActor(CharacterTemplate, FVector(0.0f, StartY, 204.6241f), FRotator(0.0f, -90.0f, 0.0f)); + Temp->AutoPossessPlayer = EAutoReceiveInput::Player1; + if(Temp) + { + P2Team.Add(Temp); + } + } +} + +void AKOFDefaultGameMode::StartPlay() +{ + Super::StartPlay(); + + InitTeams(); + + // is this the right place to do this? + APlayerController* PC1 = UGameplayStatics::GetPlayerController(GetWorld(), 0); + if(PC1) + { + AKOFBaseCharacter* P1 = GetP1CurrentCharacter(); + if(P1) + { + PC1->Possess(P1); + } + } + + APlayerController* PC2 = UGameplayStatics::GetPlayerController(GetWorld(), 1); + if(PC2) + { + AKOFBaseCharacter* P2 = GetP1CurrentCharacter(); + if(P2) + { + PC2->Possess(P2); + } + } +} diff --git a/KOFForever/Source/KOFForever/Private/GameModes/KOFTeam.cpp b/KOFForever/Source/KOFForever/Private/GameModes/KOFTeam.cpp new file mode 100644 index 0000000..1da4237 --- /dev/null +++ b/KOFForever/Source/KOFForever/Private/GameModes/KOFTeam.cpp @@ -0,0 +1,23 @@ + + + +#include "GameModes/KOFTeam.h" + +#include "Character/KOFBaseCharacter.h" + +AKOFBaseCharacter* UKOFTeam::GetCurrentCharacter() +{ + return Characters.Num() > 0 ? Characters[0] : nullptr; +} + +void UKOFTeam::InitTeam() +{ + for (TSubclassOf CharacterTemplate : CharacterTemplates) + { + AKOFBaseCharacter* Temp = NewObject(CharacterTemplate); + if(Temp) + { + Characters.Add(Temp); + } + } +} diff --git a/KOFForever/Source/KOFForever/Public/Camera/KOFDefaultCamera.h b/KOFForever/Source/KOFForever/Public/Camera/KOFDefaultCamera.h index 1a48a6c..243cc84 100644 --- a/KOFForever/Source/KOFForever/Public/Camera/KOFDefaultCamera.h +++ b/KOFForever/Source/KOFForever/Public/Camera/KOFDefaultCamera.h @@ -44,13 +44,10 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = CameraSettings) float ZAveragingFactor; - - // References to player main character's - // eventually we want to spawn all the player's characters from game mode? and then we can get the references to - // P1 and P2 from there. For now we'll just set the references manually in the level - UPROPERTY(EditAnywhere) - AActor* P1; + /** + * How far the character's have to be apart before the camera moves to keep both in frame + */ + float MovementYDistanceThreshold; - UPROPERTY(EditAnywhere) - AActor* P2; + void UpdateCamera(); }; diff --git a/KOFForever/Source/KOFForever/Public/GameModes/KOFDefaultGameMode.h b/KOFForever/Source/KOFForever/Public/GameModes/KOFDefaultGameMode.h new file mode 100644 index 0000000..700e020 --- /dev/null +++ b/KOFForever/Source/KOFForever/Public/GameModes/KOFDefaultGameMode.h @@ -0,0 +1,62 @@ + + +#pragma once + +#include "CoreMinimal.h" +#include "KOFTeam.h" +#include "Character/KOFBaseCharacter.h" +#include "GameFramework/GameModeBase.h" +#include "KOFDefaultGameMode.generated.h" + +/** + * + */ +UCLASS() +class KOFFOREVER_API AKOFDefaultGameMode : public AGameModeBase +{ + GENERATED_BODY() + +public: + AKOFDefaultGameMode(); + + TArray& GetP1Team() { return P1Team; } + + TArray& GetP2Team() { return P2Team; } + + // this will need to change when we actually have real time character switching + AKOFBaseCharacter* GetP1CurrentCharacter() { return P1Team.Num() > 0 ? P1Team[0] : nullptr; } + + // this will need to change when we actually have real time character switching + AKOFBaseCharacter* GetP2CurrentCharacter() { return P2Team.Num() > 0 ? P2Team[0] : nullptr; } + +protected: + /** Number of characters on a single player's team */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="Settings|Team") + int32 NumCharactersPerTeam; + + /** Max distance the currently controlled player characters can be from one another */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage") + float MaxDistance; + + /** Y offset from origin where character's will be spawned */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Settings|Stage") + float StartY; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team") + TArray> P1TeamTemplate; + + /** List of references to the player's team members */ + UPROPERTY(BlueprintReadOnly) + TArray P1Team; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Settings|Team") + TArray> P2TeamTemplate; + + /** List of references to the player's team members */ + UPROPERTY(BlueprintReadOnly) + TArray P2Team; + + void InitTeams(); + + virtual void StartPlay() override; +}; diff --git a/KOFForever/Source/KOFForever/Public/GameModes/KOFTeam.h b/KOFForever/Source/KOFForever/Public/GameModes/KOFTeam.h new file mode 100644 index 0000000..e5653c4 --- /dev/null +++ b/KOFForever/Source/KOFForever/Public/GameModes/KOFTeam.h @@ -0,0 +1,38 @@ + + +#pragma once + +#include "CoreMinimal.h" +#include "UObject/NoExportTypes.h" +#include "KOFTeam.generated.h" + +class AKOFBaseCharacter; +/** + * + */ +UCLASS(BlueprintType, Blueprintable) +class KOFFOREVER_API UKOFTeam : public UObject +{ + GENERATED_BODY() + +public: + /** + * Returns the character on this team that is currently on stage being controlled by the player + */ + AKOFBaseCharacter* GetCurrentCharacter(); + + void InitTeam(); + +protected: + /** + * List of character templates to spawn the player's team when the match begins. + * + * This will eventually get set by the player's choices in the character select menu + */ + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Characters") + TArray> CharacterTemplates; + + /** List of references to the player's team members */ + UPROPERTY(BlueprintReadOnly, Category="Characters") + TArray Characters; +};