diff --git a/Source/tank/CameraManagerSubsystem.cpp b/Source/tank/CameraManagerSubsystem.cpp new file mode 100644 index 0000000..3d64033 --- /dev/null +++ b/Source/tank/CameraManagerSubsystem.cpp @@ -0,0 +1,67 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "CameraManagerSubsystem.h" + +void UCameraManagerSubsystem::Initialize(FSubsystemCollectionBase& Collection) +{ + Super::Initialize(Collection); + CurrentCameraVolume = nullptr; + CameraVolumeQueue.Empty(); +} + +void UCameraManagerSubsystem::Deinitialize() +{ + Super::Deinitialize(); + CurrentCameraVolume = nullptr; + CameraVolumeQueue.Empty(); +} + +void UCameraManagerSubsystem::SetCurrentCameraVolume(ACameraVolume* CameraVolume) +{ + + if (CurrentCameraVolume != CameraVolume && !CameraVolumeQueue.Contains(CameraVolume)) + { + if (CurrentCameraVolume) + { + CurrentCameraVolume->SetIsActive(false); + } + + QueueCameraVolume(CameraVolume); + CurrentCameraVolume = CameraVolume; + CurrentCameraVolume->MoveCameraToLocation(); + } +} + +void UCameraManagerSubsystem::RemoveCameraVolume(ACameraVolume* CameraVolume) +{ + if (CameraVolume == CurrentCameraVolume) + { + CameraVolumeQueue.Remove(CameraVolume); + CurrentCameraVolume->SetIsActive(false); + CurrentCameraVolume = nullptr; + } + + if (CameraVolumeQueue.Num() > 0) + { + CurrentCameraVolume = CameraVolumeQueue.Last(); + CurrentCameraVolume->MoveCameraToLocation(); + CurrentCameraVolume->SetIsActive(true); + } +} + +void UCameraManagerSubsystem::QueueCameraVolume(ACameraVolume* CameraVolume) +{ + if (!CameraVolumeQueue.Contains(CameraVolume)) + { + CameraVolumeQueue.Push(CameraVolume); + } +} + +void UCameraManagerSubsystem::DequeueCameraVolume(ACameraVolume* CameraVolume) +{ + if (CameraVolumeQueue.Contains(CameraVolume)) + { + CameraVolumeQueue.Remove(CameraVolume); + } +} diff --git a/Source/tank/CameraManagerSubsystem.h b/Source/tank/CameraManagerSubsystem.h new file mode 100644 index 0000000..8eca49f --- /dev/null +++ b/Source/tank/CameraManagerSubsystem.h @@ -0,0 +1,41 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "CameraVolume.h" +#include "Subsystems/GameInstanceSubsystem.h" +#include "CameraManagerSubsystem.generated.h" + +/** + * + */ +UCLASS() +class TANK_API UCameraManagerSubsystem : public UGameInstanceSubsystem +{ + GENERATED_BODY() + + UPROPERTY() + TArray CameraVolumeQueue; + + UPROPERTY() + ACameraVolume* CurrentCameraVolume = nullptr; + +public: + virtual void Initialize(FSubsystemCollectionBase& Collection) override; + + virtual void Deinitialize() override; + + UFUNCTION(BlueprintCallable) + void SetCurrentCameraVolume(ACameraVolume* CameraVolume); + + UFUNCTION(BlueprintCallable) + void RemoveCameraVolume(ACameraVolume* CameraVolume); + +private: + UFUNCTION(BlueprintCallable) + void QueueCameraVolume(ACameraVolume* CameraVolume); + + UFUNCTION(BlueprintCallable) + void DequeueCameraVolume(ACameraVolume* CameraVolume); +}; diff --git a/Source/tank/CameraVolume.cpp b/Source/tank/CameraVolume.cpp index f316260..4aa5f29 100644 --- a/Source/tank/CameraVolume.cpp +++ b/Source/tank/CameraVolume.cpp @@ -2,6 +2,8 @@ #include "CameraVolume.h" + +#include "CameraManagerSubsystem.h" #include "TankPlayerCharacter.h" #include "Kismet/KismetMathLibrary.h" @@ -35,15 +37,34 @@ void ACameraVolume::Tick(float DeltaSeconds) } } +void ACameraVolume::MoveCameraToLocation() +{ + if (TankPlayerCharacter) + { + TankPlayerCharacter->CameraComponent->SetWorldLocation(ArrowComponent->GetComponentTransform().GetLocation()); + TankPlayerCharacter->CameraComponent->SetWorldRotation(ArrowComponent->GetComponentTransform().GetRotation()); + } +} + +bool ACameraVolume::GetIsActive() +{ + return IsActive; +} + +void ACameraVolume::SetIsActive(bool bActive) +{ + IsActive = bActive; +} + void ACameraVolume::OnBeginOverlap(AActor* OverlappedActor, AActor* OtherActor) { if (ATankPlayerCharacter* PlayerCharacter = Cast(OtherActor)) { - PlayerCharacter->CameraComponent->SetWorldLocation(ArrowComponent->GetComponentTransform().GetLocation()); - PlayerCharacter->CameraComponent->SetWorldRotation(ArrowComponent->GetComponentTransform().GetRotation()); - TankPlayerCharacter = PlayerCharacter; IsActive = true; + + auto CameraManagerSubsystem = GetGameInstance()->GetSubsystem(); + CameraManagerSubsystem->SetCurrentCameraVolume(this); } } @@ -51,4 +72,7 @@ void ACameraVolume::OnEndOverlap(AActor* OverlappedActor, AActor* OtherActor) { IsActive = false; TankPlayerCharacter = nullptr; + + auto CameraManagerSubsystem = GetGameInstance()->GetSubsystem(); + CameraManagerSubsystem->RemoveCameraVolume(this); } diff --git a/Source/tank/CameraVolume.h b/Source/tank/CameraVolume.h index 7c9876e..516793f 100644 --- a/Source/tank/CameraVolume.h +++ b/Source/tank/CameraVolume.h @@ -45,6 +45,15 @@ protected: public: virtual void Tick(float DeltaSeconds) override; + UFUNCTION() + void MoveCameraToLocation(); + + UFUNCTION() + bool GetIsActive(); + + UFUNCTION() + void SetIsActive(bool bActive); + private: UFUNCTION() void OnBeginOverlap(AActor* OverlappedActor, AActor* OtherActor);