본문 바로가기
Study/Unreal

[Unreal/정리] 보스존 트리거

by generous_jeans 2020. 11. 14.

- 보스존 카메라 무브 트리거 -

// 보스존에 들어갔을 때 카메라가 움직이는 것. 

 

// 보스존 생성.

(언리얼 에디터) 지오메트리-박스 배치 : 보스존 생성

 

// 디테일 -> Brush Settings-Brush Type : "Additve" : 월드에 더함

// 디테일 -> Brush Settings-Brush Type : "Subtractive" : 월드에서 뺌. 보이지 않음. 

// 디테일 -> 표면 머터리얼 : 이미지 입힘. 

 

(언리얼 에디터) LandScape -> 우클릭_머터리얼 : "MTBossWall"

(언리얼 에디터-MTBossWall)  

 

// 보스존 트리거.

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

 

(C++-BossZone.h)

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

#pragma once

#include "GameInfo.h"
#include "GameFramework/Actor.h"
#include "BossZone.generated.h"

UCLASS()
class UE7PROJECT_API ABossZone : public AActor
{
    GENERATED_BODY()
	
public:	
    // Sets default values for this actor's properties
    ABossZone();

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    class UBoxComponent* Box;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    TArray<class APoint*> CameraMovePointArray;

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:	
    // Called every frame
    virtual void Tick(float DeltaTime) override;
    
};

(C++-BossZone.cpp)

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


#include "BossZone.h"
#include "MoveCamera.h"
#include "Point.h"

// Sets default values
ABossZone::ABossZone()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    Box = CreateDefaultSubobject<UBoxComponent>(TEXT("Box"));

    SetRootComponent(Box);

    Box->SetCollisionProfileName(TEXT("Trigger"));

}

// Called when the game starts or when spawned
void ABossZone::BeginPlay()
{
    Super::BeginPlay();

}

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

}


(언리얼 에디터) 보스존 입구 앞에 BossZone 배치

 

// 위치 정보를 표시하는 클래스.

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

 

(C++-Point.h)

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

#pragma once

#include "GameInfo.h"
#include "GameFramework/Actor.h"
#include "Point.generated.h"

UCLASS()
class UE7PROJECT_API APoint : public AActor
{
    GENERATED_BODY()
	
public:	
    // Sets default values for this actor's properties
    APoint();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:	
    // Called every frame
    virtual void Tick(float DeltaTime) override;

};

(C++-Point.cpp)

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


#include "Point.h"

// Sets default values
APoint::APoint()
{
    // Set tor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = false;

}

// Called when the game starts or when spawned
void APoint::BeginPlay()
{
    Super::BeginPlay();
	
}

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

}

// 카메라가 전환할 위치 설정

(언리얼 에디터) LandScape -> 우클릭_블루프린트 클래스 -> 부모 : " " 이름 : "BPPoint"

(언리얼 에디터) BPPoint 배치  // 카메라가 이동할 위치에 배치. 

 

(언리얼 에디터) BossZone -> 디테일 -> Boss Zone-Camera Move Point.. : BPPoint와 연결

 

// 이벤트 카메라. 다른 액터에 부착되어 이동하다가 다시 플레이어에 부착. 

(C++-BossZone.h)

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

#pragma once

#include "GameInfo.h"
#include "GameFramework/Actor.h"
#include "BossZone.generated.h"

UCLASS()
class UE7PROJECT_API ABossZone : public AActor
{
    GENERATED_BODY()
	
public:	
    // Sets default values for this actor's properties
    ABossZone();

protected:
    UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    class UBoxComponent* Box;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    TArray<class APoint*> CameraMovePointArray;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true"))
    class AMoveCamera* MoveCamera;

    int32 PointIndex;
    FTimerHandle BlendTimerHandle;
    FTimerHandle ChangeTimerHandle;

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:	
    // Called every frame
    virtual void Tick(float DeltaTime) override;

public:
    UFUNCTION()
    void TriggerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

    UFUNCTION()
    void TriggerEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex);

    UFUNCTION()
    void StartEvent();

    UFUNCTION()
    void EndEvent();
    
    UFUNCTION()
    void CameraBlendEnd();

    UFUNCTION()
    void CameraChangeEnd();
};

 

(C++-BossZone.cpp)

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


#include "BossZone.h"
#include "MoveCamera.h"
#include "Point.h"

// Sets default values
ABossZone::ABossZone()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

    Box = CreateDefaultSubobject<UBoxComponent>(TEXT("Box"));

    SetRootComponent(Box);

    Box->SetCollisionProfileName(TEXT("Trigger"));

    PointIndex = 0;

}

// Called when the game starts or when spawned
void ABossZone::BeginPlay()
{
    Super::BeginPlay();

    Box->OnComponentBeginOverlap.AddDynamic(this, &ABossZone::TriggerBeginOverlap);
    Box->OnComponentEndOverlap.AddDynamic(this, &ABossZone::TriggerEndOverlap);
    
    // 이동할 때 카메라가 회전하도록 설정.
    int32 iCount = CameraMovePointArray.Num();

    for (int32 i = 0; i < iCount - 1; ++i)
    {
        // 다음 위치에서 현재 위치를 빼면 바라볼 위치가 나옴.
        FVector	vDir = CameraMovePointArray[i + 1]->GetActorLocation() - CameraMovePointArray[i]->GetActorLocation();
        vDir.Normalize();
        
        CameraMovePointArray[i]->SetActorRotation(vDir.Rotation());
    }
}

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

}

void ABossZone::TriggerBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
    StartEvent();  // 이벤트 시작.
}

void ABossZone::TriggerEndOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex)
{
}

void ABossZone::StartEvent() // StartEvnet에서 CameraMovePointArray[0]으로 이동하도록 설정.
{
    if (!IsValid(MoveCamera))
        return;

    PointIndex = 0;

    APlayerController* Controller = GetWorld()->GetFirstPlayerController();
    
    // Controller->SetViewTarget(MoveCamera);
    Controller->SetViewTargetWithBlend(MoveCamera, 0.5f, EViewTargetBlendFunction::VTBlend_EaseInOut, 0.5f);
    // 카메라의 움직임을 부드럽게 연결해줌. 
    // 두 위치 사이를 보간처리해서 부드럽게 연결함. 시간을 조절하여 만들어줄 수 있음. 
    
    // 언리얼에서는 타이머 기능을 제공해줌. 
    // 타이머 기능을 사용하면 지정한 시간이 지나면 다음 기능을 사용할 수 있게 처리함. 
    // 블렌드가 종료될때 호출될 타이머를 생성.
    GetWorldTimerManager().SetTimer(BlendTimerHandle, this, &ABossZone::CameraBlendEnd, 0.5f, true);
}

void ABossZone::EndEvent()  // 이동이 끝났으므로 원래 위치로 돌아가도록 설정. 
{
    PointIndex = 0;

    APlayerController* Controller = GetWorld()->GetFirstPlayerController();

    Controller->SetViewTargetWithBlend(Controller->GetPawn(), 2.f, EViewTargetBlendFunction::VTBlend_EaseInOut, 0.5f);
}

void ABossZone::CameraBlendEnd()  // StartEvnet에서 이동이 끝나면 CameraMovePointArray[0]의 다음으로 이동하도록 설정. 
{
    GetWorldTimerManager().ClearTimer(BlendTimerHandle);

    APlayerController* Controller = GetWorld()->GetFirstPlayerController();

    Controller->SetViewTargetWithBlend(CameraMovePointArray[PointIndex], 1.f, EViewTargetBlendFunction::VTBlend_EaseInOut, 0.5f);

    // 블렌드가 종료될때 호출될 타이머를 생성.
    GetWorldTimerManager().SetTimer(ChangeTimerHandle, this, &ABossZone::CameraChangeEnd, 1.f, true);
}

void ABossZone::CameraChangeEnd()
{
    GetWorldTimerManager().ClearTimer(ChangeTimerHandle);

    ++PointIndex;  // index가 1씩 증가하여 다음 위치로 이동하도록 설정. 

    if (PointIndex >= CameraMovePointArray.Num())  // 이동이 끝나면 EndEvent 실행. 
        EndEvent();
    else
    {
        APlayerController* Controller = GetWorld()->GetFirstPlayerController();

        Controller->SetViewTargetWithBlend(CameraMovePointArray[PointIndex], 1.f, EViewTargetBlendFunction::VTBlend_EaseInOut, 0.5f);

        // 블렌드가 종료될때 호출될 타이머를 생성.
        GetWorldTimerManager().SetTimer(ChangeTimerHandle, this, &ABossZone::CameraChangeEnd, 1.f, true);
    }
}

 

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

 

(C++-MoveCamera.h)

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

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MoveCamera.generated.h"

UCLASS()
class UE7PROJECT_API AMoveCamera : public AActor
{
    GENERATED_BODY()
	
public:	
    // Sets default values for this actor's properties
    AMoveCamera();

protected:
    // Called when the game starts or when spawned
    virtual void BeginPlay() override;

public:	
    // Called every frame
    virtual void Tick(float DeltaTime) override;

};

(C++-MoveCamera.cpp)

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


#include "MoveCamera.h"

// Sets default values
AMoveCamera::AMoveCamera()
{
    // Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
    PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void AMoveCamera::BeginPlay()
{
    Super::BeginPlay();
	
}

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

}

 

(언리얼 에디터) Player -> 우클릭_블루프린트 클래스 -> 부모 : "MoveCamera" 이름 : "BPMoveCamera"

 

(언리얼 에디터) 보스존 입구 앞에 BPMoveCamera 배치

 

(언리얼 에디터) BossZone -> 디테일 -> Boss Zone-Move Camera. : BPMoveCamera와 연결

 

// 보스존에 들어가서 카메라가 이동하는 동안 플레이어가 움직이지 않도록 입력을 받는 것을 막아야 함. 

댓글