프로그래밍 공부
작성일
2024. 5. 22. 16:02
작성자
WDmil
728x90

3인칭 FPS게임의 기본사항인 3인칭뷰 와 1인칭 뷰를 전환하면서 사용할 수 있다.

 

Aim과 Hip에 대한 애니메이션 전환을 사용할 수 있다.


ABP 재설정

 

컨듀잇과 스테이트 에일리어스 를 사용하여 ABP의 간선을 정리한다.

 


컨듀잇(Conduit)

 

ABP에서 애니메이션 끼리의 연결과정이 너무 복잡해질 때 사용한다.

일정 조건 하에 컨듀잇 으로 애니메이션 노드가 이동하게 되며, 컨듀잇에서 노드를 재정리한다.

Is Aiming이 컨듀잇 이다.

 

컨듀잇에 들어온 노드는, 해당사항이 있을 경우, 내려가는 노드로 이동한다.

위 이미지에서는 해당되는 bool값이 false일경우 좌측, true일경우 우측으로 애니메이션 노드를 이동시킨다.

 

 

 


스테이트 에일리어스(State Alias)

 

애니메이션 노드의 지정된 조건이 True가 되었을 경우 연결된 에니메이션 스테이트 를 실행하는 역할을 한다.

주로, 복잡해진 애니메이션 스테이트들의 연결을 최적화하기 위해 사용된다.

윗부분의 분홍색 부분이 스테이트 에일리어스 이다.


 

애니메이션 재설정을 위해 데이터를 정의한다.

노드 연결은 위와 같다.

 

Movement에서 애니메이션의 행동을 연결하고, Turn시, 지정된 Turn애니메이션을 실행한 뒤에 IsAiming인 컨듀잇을 통과하여 현재 상태가 Aim인지 아닌지 확인하고, Movement로 복귀할지, RifleAiming으로 복귀할지 판단 이동한다.

 

Aiming_To_HipFire와 HipFire_To_Aiming은 조준상태를 판별하기 위한 노드이다.

노드에서 사용하는 bool은 다음 한개를 사용한다.

 

bool bAiming


ABP에 전달하는 Bool값 연동.

 

먼저, 키값에 사용하는 Bool을 컨트롤 해야하기 때문에, 인풋값을 연동해준다.

#pragma once

#include "CoreMinimal.h"
#include "FTPSGameCharacter.h"
#include "Actors/BaseCharacter.h"
#include "Datas/CharacterStruct.h"
#include "Hero.generated.h"

class IInteract;
class UInputMappingContext;
class UInputAction;

/**
 * 
 */
UCLASS()
class FTPSGAME_API AHero : public ABaseCharacter
{
	GENERATED_BODY()

	// Components
	UPROPERTY(VisibleDefaultsOnly, Category = Camera)
	TObjectPtr<USpringArmComponent> SpringArm;

	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Camera, meta = (AllowPrivateAccess = "true"))
	TObjectPtr<UCameraComponent> Camera;
	
	// Input Actions
	UPROPERTY(EditDefaultsOnly, Category = Input, meta=(AllowPrivateAccess="true"))
	TObjectPtr<UInputAction> MoveAction;

	UPROPERTY(EditDefaultsOnly, Category = Input, meta=(AllowPrivateAccess="true"))
	TObjectPtr<UInputAction> ViewAction;

	UPROPERTY(EditDefaultsOnly, Category = Input, meta=(AllowPrivateAccess="true"))
	TObjectPtr<UInputAction> JumpAction;

	UPROPERTY(EditDefaultsOnly, Category = Input, meta=(AllowPrivateAccess="true"))
	TObjectPtr<UInputMappingContext> InputMappingContext;

	UPROPERTY(EditDefaultsOnly, Category = Input, meta=(AllowPrivateAccess="true"))
	FInputStruct CombatInput;


	
public:
	AHero();

	virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

	void CameraHold(bool bValue);
	virtual FVector GetControlLocation() override;
	
private:
	virtual void BeginPlay() override;

private:
	void Move(const FInputActionValue& Value);
	void View(const FInputActionValue& Value);

	void SelectMainHolder();
	void SelectSubHolder();



	virtual void Interact() override;
	virtual void InteractCanceled() override;
	virtual void InteractComplete() override;
	

	void BindingDefaultActions(UEnhancedInputComponent* EnhancedInputComponent);
	void BindingCombatActions(UEnhancedInputComponent* EnhancedInputComponent);

protected:
	virtual void AimingDownSight() override;

	UFUNCTION(BlueprintNativeEvent)
	void Aiming();

	UFUNCTION(BlueprintNativeEvent)
	void HipFire();


};
void AHero::Aiming_Implementation()
{
	Super::Aiming();
	bAiming = true;
	bAimingDownSight = false;
	CameraHold(true);
}

void AHero::HipFire_Implementation()
{
	Super::HipFire();
	bAiming = false;
	bAimingDownSight = false;

	CameraHold(false);
}

void AHero::BindingCombatActions(UEnhancedInputComponent* EnhancedInputComponent)
{
	// Interact
	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("Interact"), ETriggerEvent::Ongoing, this, &AHero::Interact);
	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("Interact"), ETriggerEvent::Canceled, this, &AHero::InteractCanceled);

	// Select Holder
	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("MainHolder"), ETriggerEvent::Triggered, this, &AHero::SelectMainHolder);
	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("SubHolder"),  ETriggerEvent::Triggered, this, &AHero::SelectSubHolder);

	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("AimingDownSight"), ETriggerEvent::Ongoing, this, &AHero::Aiming);
	EnhancedInputComponent->BindAction(*CombatInput.InputActionMap.Find("AimingDownSight"), ETriggerEvent::Completed, this, &AHero::HipFire);
}

 

위와같이 AimingDownSight키값을 연동해서 마우스 우측클릭을 했을 때 조준할 수 있도록 해준다.

C++에서 정의해놓은 input Action Map에 집어넣어준다.


카메라 무브먼트 설정

 

3인칭 FPS게임에서 조준했을 때, 1인칭처럼 카메라가 이동하는건 흔한 방식이다. 이러한 방식을 구현해보자.

 

 

조준했을 때 타임라인의 키프레임값을 활용하여 카메라의 FOV와 Y값을 조정할 것이다.

타임라인은 위와같이 조정한다. 처음 FOV값은, 90 마지막값은 45로,

CameraY값은 처음값은 0에 마지막값은,50으로 조정한다.

 

카메라의 Play와 Reverse에 이벤트그래프를 연결하여 조정한다.

 

Play시에는 정방향으로, Reverse시 에는 역방향으로 값이 이동된다.

 

Camera의 Y값을, FieldOfView는 FOV값을 집어넣어 조정한다.


테스트

 

 

728x90