공부/Unreal

24.08.20

월러비 2024. 8. 23. 14:04

무기시스템 - 활

보조 엑션 클래스 생성 및 준비

  • Equipment, DoAction과 같이 UObject이하로 상속을 받아야지 ‘직렬화’가 가능하다.
    • 데이터만 다루는 클래스들이다.
  • DoAction과 SubAction은 생성 비율이 1 : N 관계이다.
    • 무기별 또는 파쿠르 같은 보조 엑션들이 여러개 생성될 것이기 때문이다.
  • CSubAction
    • 생성
    • 엑션과 같은 구조를 가진다.
    • 무기별 스킬을 실행할 클래스다.
    • 원래는 Attachment나 DoAction을 소유하면 안되지만 ‘개념’ 정도로 두기 때문에 소유할 수 있는 것이다.
    • DoAction처럼 SubAction을 상속받아 각각의 보조 엑션 클래스를 생성하고, 또 그것으로 블루프린트 파일을 만들어 할당하는 것으로 사용된다.
    • 헤더 파일 - 생성자 선언 - 임의의 BeginPlay 함수를 ‘가상화’ 시켜 선언하고 ‘오너 캐릭터, Attachment, DoAction’을 받는다. - ‘오너 캐릭터’ , ‘Attachment’ , ‘DoAction’ , 상태 컴포넌트 클래스의 ‘상태’ , 움직임 컴포넌트의 ‘움직임’ 변수를 선언한다. - ‘서브 엑션 확인’ 변수 선언 - ‘누름’ 함수와 ‘땜’ 함수 선언하고 ‘가상화’ 시킨다. - ‘서브 엑션 확인 가져오기’ 함수를 선언하고 ‘서브 엑션 확인’ 변수 반환으로 정의한다.
    //header
    public:
    	//외부에서 엑션 확인하는 변수 사용
    	FORCEINLINE bool GetInAction() { return bInAction; }
    
    public:
    	UCSubAction();
    
    public:
    	virtual void BeginPlay(class ACharacter* InOwner, class ACAttachment* InAttachment, class UCDoAction* InDoAction);
    
    public:
    	virtual void Pressed(); //누름 함수
    	virtual void Released(); //땜 함수
    
    protected:
    	bool bInAction; //엑션 중인지 확인
    
    	class ACharacter* Owner;
    	class ACAttachment* Attachment;
    	class UCDoAction* DoAction;
    
    	class UCStateComponent* State;
    	class UCMovementComponent* Movement;
    
    • CPP 파일 - 임의의 BeginPlay 함수 정의 - ‘오너 캐릭터’ , ‘Attachment’ , ‘DoAction’ , 상태 컴포넌트 클래스의 ‘상태’ , 움직임 컴포넌트의 ‘움직임’ 변수에 매개변수로 들어온 값과 ‘오너 캐릭터’의 ‘컴포넌트 가져오기’ 함수를 호출하여 저장한다. - ‘누름’ 함수와 ‘땜’ 함수 정의 - ‘서브 엑션 확인’ 변수에 true, false를 설정한다.
    //CPP
    void UCSubAction::BeginPlay(ACharacter* InOwner, ACAttachment* InAttachment, UCDoAction* InDoAction)
    {
    	Owner = InOwner;
    	Attachment = InAttachment;
    	DoAction = InDoAction;
    
    	State = CHelpers::GetComponent<UCStateComponent>(Owner);
    	Movement = CHelpers::GetComponent<UCMovementComponent>(Owner);
    }
    
    void UCSubAction::Pressed()
    {
    	bInAction = true;
    }
    
    void UCSubAction::Released()
    {
    	bInAction = false;
    }
    
  • CWeaponAsset
    • SubAction은 클래스 타입을 받아서 변수로 사용할 것이다.
    • SubAction은 DoActionData와 HitData에 있을수도 있고, 없을 수도 있기 때문에 선언에 직접 할당하지 않고, 필요하면 ‘블루프린트 파일’을 만들어 할당할 것이다.
    • 나중에는 SubAction을 여러개 만들것이니 ‘SubActionClasses’ ‘배열 변수’로 선언해야한다.
    • 헤더 파일 - 클래스 변수로 ‘SubAction 클래스’ 변수 선언 - 서브 엑션 클래스의 ‘서브 엑션’ 변수 선언 - ‘서브 엑션 가져오기’ 함수를 선언하고 ‘SubAction’을 반환하는것으로 정의한다.
    //header
    //여러개의 스킬일때는 서브엑션즈로 배열을 만들어라
    UPROPERTY(EditAnywhere)
    	TSubclassOf<class UCSubAction> SubActionClass;
    
    FORCEINLINE class UCSubAction* GetSubAction() { return SubAction; }
    
    UPROPERTY()
    		class UCSubAction* SubAction;
    
    • CPP 파일 - BeginPlay 함수 확인 - ‘서브 엑션 클래스’ 변수가 비어있지 않다면 : ‘새 오브젝트 생성’ 함수를 서브 엑션 클래스로 지정하고 ‘관리할 클래스 : 웨폰 에셋, 생성할 클래스 : 서브 엑션 클래스’를 넣어 호출한 결과를 ‘서브 엑션’ 변수에 저장한다. - ‘서브 엑션’의 ‘BeginPlay’ 함수에 ‘오너 캐릭터, Attachment, DoAction’을 넣고 호출한다.
    //CPP
    if (!!SubActionClass)
    {
    	SubAction = NewObject<UCSubAction>(this, SubActionClass);
    	SubAction->BeginPlay(InOwner, Attachment, DoAction);
    }
    
  • CWeaponComponent
    • 헤더 파일 - ‘서브 엑션 가져오기’ 함수를 선언한다. - ‘서브엑션 눌림’ 함수와 ‘서브엑션 땜’ 함수를 선언한다.
    //header
    class UCSubAction* GetSubAction();
    
    public:
    	void SubAction_Pressed();
    	void SubAction_Released();
    
    • CPP 파일 - ‘서브 엑션 가져오기’ 함수 정의 - GetDoAction과 같지만 ‘GetSubAction’ 반환으로 바꾼다. - ‘서브엑션 눌림’ 함수와 ‘서브엑션 땜’ 함수 정의 - ‘서브 엑션 가져오기’ 함수가 비어있지 않다면 : ‘서브 엑션 가져오기’ 함수 호출의 ‘눌림’ ‘땜’ 함수를 호출한다.
    //CPP
    UCSubAction* UCWeaponComponent::GetSubAction()
    {
    	CheckTrueResult(IsUnarmedMode(), nullptr);
    	CheckFalseResult(!!DataAssets[(int32)Type], nullptr);
    
    	return DataAssets[(int32)Type]->GetSubAction();
    }
    
    void UCWeaponComponent::SubAction_Pressed()
    {
    	if (!!GetSubAction())
    		GetSubAction()->Pressed();
    }
    
    void UCWeaponComponent::SubAction_Released()
    {
    	if (!!GetSubAction())
    		GetSubAction()->Released();
    }
    
  • CPlayer
    • CPP 파일 - ‘서브 엑션 활성’ 함수 확인 - ‘웨폰’의 ‘비 장착 모드 확인’ 함수가 true가 아니라면 : ‘상태’ 변수의 ‘기본 모드 확인’ 함수의 호출이 false라면 실행하지 않고, true 라면 ‘파쿠르’의 ‘파쿠르 실행’ 함수를 호출하고 반환한다. - 무기를 들고있는 상태라면 ‘웨폰’의 ‘서브엑션 누름’ 함수를 호출한다. - ‘서브 엑션 비활성’ 함수 확인 - ‘웨폰’의 ‘비 장착 모드 확인’ 함수를 호출하고 true라면 실행하지 않는다. - ‘웨폰’의 ‘서브 엑션 땜’ 함수를 호출한다.
    //CPP
    void ACPlayer::OnSubAction()
    {
    	if (Weapon->IsUnarmedMode())
    	{
    		CheckFalse(State->IsIdleMode());
    
    		Parkour->DoParkour();
    
    		return;
    	}
    
    	//무기를 들고있다면 : 스킬 실행
    	Weapon->SubAction_Pressed();
    }
    
    void ACPlayer::OffSubAction()
    {
    	//무기를 안들고있다면 : 스킬 말고 파쿠르 실행
    	CheckTrue(Weapon->IsUnarmedMode());
    
    	Weapon->SubAction_Released();
    }
    
  • CSubAction_Bow
    • 생성
    • 헤더 파일 - 생성자 선언 - ‘누름’ ‘땜’ 함수 재정의 선언
    //header
    public:
    	UCSubAction_Bow();
    
    public:
    	void Pressed() override;
    	void Released() override;
    
    • CPP 파일 - ‘누름’ 함수 정의 - 부모 함수 호출 - ‘땜’ 함수 정의 - 부모 함수 호출 - 함수 호출 되는지 테스트
    //CPP
    void UCSubAction_Bow::Pressed()
    {
    	Super::Pressed();
    
    }
    
    void UCSubAction_Bow::Released()
    {
    	Super::Released();
    
    }
    
  • BP_CSubAction_Bow
    • 생성
  • DA_Bow
    • SubActionClass 할당

활 보조 엑션 - 조준 상태

  • CAnimInstance
    • 헤더 파일 - ‘활 조준중 확인’ 변수 선언 - 웨폰 타입이 바뀔때 바뀐것을 알려야 할때 필요한 함수인 ‘웨폰 타입 변경됨 활성’ 함수를 선언하고 ‘전 웨폰 타입, 새로운 웨폰 타입’을 넣고 선언한다. - 시점의 각도를 조절할 ‘피치’ 변수 선언
    //header
    UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
    		float Pitch;
    
    protected:
    	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
    		bool bBow_Aiming; //활 조준중인지 확인
    
    private:
    	//웨폰 타입이 바뀔때 연결할 함수다.
    	UFUNCTION()
    		void OnWeaponTypeChanged(EWeaponType InPrevType, EWeaponType InNewType);
    
    • CPP 파일 - ‘웨폰’이 비어있는지 확인한다. : 비었으면 실행 안한다. - ‘웨폰’의 ‘서브 엑션 가져오기’ 함수 호출이 비어있지 않다면 : ‘활 조준중 확인’ 변수를 true로 설정한다. , ‘활 조준중 확인’ 변수에 ‘웨폰타입’과 ‘웨폰 타입 열거형 : 활’이 같다면 ‘1’ 아니면 ‘0’을 저장한다. , ‘활 조준중 확인’ 변수에 ‘웨폰’의 ‘서브 엑션 가져오기’ 함수 호출의 ‘서브 엑션 확인 가져오기’ 함수 호출결과를 저장한다. - ‘웨폰 타입 변경됨 활성’ 함수 정의 - ‘웨폰 타입’에 ‘새로운 타입’을 저장한다. - BeginPlay 함수 확인 - ‘웨폰’이 비어있지 않다면 : ‘웨폰’의 ‘웨폰 타입 변경됨 활성’ 함수의 함수 연결 함수에 (함수가 있는 클래스 : 애님 인스턴스 클래스, 연결할 함수 : 웨폰 타입 변경됨 활성’을 넣고 호출한다. - 키즈멧 메스 자료형의 ‘float 보간’ 함수에 ‘피치, 오너캐릭터의 에임 회전값 가져오기 함수 호출의 피치값, 보간 시간 : 델타 세컨즈, 보간 속도 : 25’을 넣고 호출하고 ‘피치’에 저장한다.
    //CPP
    //FInterpTo : float값으로 보간(R은 회전값으로 보간)
    //조준 각도 설정
    Pitch = UKismetMathLibrary::FInterpTo(Pitch, OwnerCharacter->GetBaseAimRotation().Pitch, DeltaSeconds, 25);
    
    if (!!Weapon)
    		Weapon->OnWeaponTypeChanged.AddDynamic(this, &UCAnimInstance::OnWeaponTypeChanged);
    
    CheckNull(Weapon);
    
    if (!!Weapon->GetSubAction())
    {
    	bBow_Aiming = true;
    	bBow_Aiming &= WeaponType == EWeaponType::Bow;
    	bBow_Aiming &= Weapon->GetSubAction()->GetInAction();
    }
    
    void UCAnimInstance::OnWeaponTypeChanged(EWeaponType InPrevType, EWeaponType InNewType)
    {
    	WeaponType = InNewType;
    }
    
  • ABP_Character
    • 하체는 ‘활’ 기본 이동 동작, 상체는 ‘활 조준’ 동작을 사용한다.
    • 지금은 상체 하체 나누는 본을 ‘spine_02’로 했지만 나중에 더 자연스러운 본으로 바꿔도 된다.
    • 뎁스 블렌딩 : 1 (1로 설정하면 두 동작이 완전히 섞인다.)
    • 에임 오프셋의 Base Pose 연결 주의점 ; 에임 오프셋의 기준 애니메이션이 이전 노드에서 실행이 되어있어야한다.
    • 애니메이션의 Alpha 값은 모두 ‘얼마만큼 애니메이션을 섞을지’를 나타내는 값이다.
      • 1 : 애니메이션들을 완전히 섞는다는 의미이다.
      • 기본 1로 놓고 안보이도록 디테일 - 알파 - ‘핀으로 노출’ 체크 해제한다.
    • ‘활 레이어’ 확인 - ‘부울로 포즈 블렌딩’ 검색 - ‘활 조준중 확인’ 변수 검색 후 Active Value핀에 연결 - BS_Bow 노드는 조준중이 아닐때 실행될 노드이니 ‘False 포즈’ 핀에 연결 - BS_Bow 복사 후 ‘본 별로 레이어로 블렌딩’ 검색 후 ‘Base Pose’ 핀에 연결한다. : 조준 중 이동하면서 조준할 수 있도록 하기 위해서다. - 에임 오프셋의 기준 동작이 되는 애니메이션을 ‘Blend Pose’ 핀에 연결한다. - ‘본 별로 레이어로 블렌딩’ 노드의 디테일 , 레이어 설정 , 인덱스 , 분기 필터 추가 , 인덱스 , 본 이름 : 상체 하체 나뉘는 본 , 뎁스 블렌딩 : 1 (1로 설정하면 두 동작이 완전히 섞인다.) , 메시 스페이스 회전 : 체크 - 설정 끝난 ‘본 별로 레이어로 블렌딩’ 노드 핀을 ‘True 포즈’ 핀에 연결한다. - ‘활 에임 오프셋’ 노드 끌어다 놓고 ‘활 조준 동작’ 결과 노드를 ‘Base Pose’로 놓는다. - 에임 오프셋의 가로축 값인 ‘피치’ 핀에 넣을 ‘피치’ 를 검색하고 연결한다. - 최종 애니메이션 포즈 노드와 연결한다.

조준 시야각 제한

  • 조준할때 -90과 90 까지 안가도록 설정한다.
  • CAttachment_Bow
    • Min값과 Max값을 따로따로 선언해도 좋지만, FVector2D로 X는 최솟값 ‘ Y는 최대값으로 설정하여 사용할 수도 있다.
    • 헤더 파일 - ‘원본 피치 범위’ 변수 선언
    • CPP 파일 - ‘장착 시작 활성’ 함수 확인 - ‘오너 캐릭터’의 ‘컨트롤러 가져오기’ 함수를 ‘플레이어 컨트롤러’로 지정하고 호출한 결과를 ‘컨트롤러’ 변수를 선언하고 저장한다. - ‘컨트롤러’가 비었는지 확인한다. - ‘원본 피치 범위’의 ‘X’에 ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최솟값’을 저장한다. - ‘원본 피치 범위’의 ‘Y’에 ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최대값’을 저장한다. - ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최솟값’에 ‘제한 피치 범위’의 ‘X’ 값을 저장한다. - ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최대값’에 ‘제한 피치 범위’의 ‘Y’ 값을 저장한다. - ‘장착 해제 활성’ 함수 확인 - ‘오너 캐릭터’의 ‘컨트롤러 가져오기’ 함수를 ‘플레이어 컨트롤러’로 지정하고 호출한 결과를 ‘컨트롤러’ 변수를 선언하고 저장한다. - ‘컨트롤러’가 비었는지 확인한다. - ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최솟값’에 ‘원본 피치 범위’의 ‘X’ 값을 저장한다. - ‘컨트롤러’의 ‘플레이어 카메라 메니저’의 ‘피치 최대값’에 ‘원본 피치 범위’의 ‘Y’ 값을 저장한다.
    //CPP
    void ACAttachment_Bow::OnBeginEquip_Implementation()
    {
    	Super::OnBeginEquip_Implementation();
    
    	AttachTo("Hand_Bow_Left"); //활 왼손에 장착
    
    	//시야각 제한 설정
    	APlayerController* controller = OwnerCharacter->GetController<APlayerController>();
    	CheckNull(controller);
    
    	//카메라 Pitch값 최소 최대 저장
    	OriginViewPitchRange.X = controller->PlayerCameraManager->ViewPitchMin;
    	OriginViewPitchRange.Y = controller->PlayerCameraManager->ViewPitchMax;
    
    	controller->PlayerCameraManager->ViewPitchMin = ViewPitchRange.X;
    	controller->PlayerCameraManager->ViewPitchMax = ViewPitchRange.Y;
    
    }
    
    void ACAttachment_Bow::OnUnequip_Implementation()
    {
    	Super::OnUnequip_Implementation();
    
    	AttachTo("Holster_Bow");
    
    	//시야각 제한 설정
    	APlayerController* controller = OwnerCharacter->GetController<APlayerController>();
    	CheckNull(controller);
    
    	controller->PlayerCameraManager->ViewPitchMin = OriginViewPitchRange.X;
    	controller->PlayerCameraManager->ViewPitchMax = OriginViewPitchRange.Y;
    }
    

조준하면서 이동 설정

  • CArrow
    • CPP 파일 - ‘캡슐’의 ‘콜리전 활성화 설정’ 함수에 ‘콜리전 설정 : 충돌 안함’으로 설정한다.
    //CPP
    //화살 충돌체 비활성화
    Capsule->SetCollisionEnabled(ECollisionEnabled::NoCollision);
    
  • BP_CArrow
    • 스테틱 메쉬 확인 - 디테일 - 콜리전 - 콜리전 프리셋 : NoCollision으로 설정한다.

줌 인, 줌 아웃

  • 스프링 암
    • 타깃 암 길이 : 캐릭터와 카메라가 떨어지는 거리다.
    • 소켓 오프셋 : 스프링 암의 끝인 카메라의 위치를 조정한다.
      • 회전 중심에 영향을 미치지 않고, 캐릭터와 일정 거리를 유지하게 된다.
      • 릴레이티브 좌표다
    • 타겟 오프셋 : 캐릭터를 바라보는 시점을 유지하고 현재 카메라 월드 위치에서 보고있는 위치를 조정할때 보정을 주는 값이다.
      • 스프링 암의 뿌리, 대상에 부착되는 위치를 조정한다. (기본값은 캐릭터의 뒷목 아랫부분이다.)
      • 즉, 캐릭터가 중심이 아니라 다른 중심이 있고, 그것을 기준으로 회전하는 요소다.
      • 월드 좌표다.
  • CSubAction_Bow
    • 헤더 파일 - 에임 데이터를 모을 구조체 선언 - ‘타깃 암 길이’ 변수를 선언하고 100으로 초기화한다. - ‘소켓 오프셋’ 변수를 선언하고 (0, 30, 10)으로 초기화한다. - ‘카메라 레그 활성화 확인’ 변수 선언 - ‘카메라 위치’ 변수 선언 - 선언한 구조체 자료형을 사용하기 위해 ‘에임 데이터’ 변수 선언 - 에임 데이터의 원본값을 저장할 ‘원본 데이터’ 변수 선언 - 조정할 ‘스프링 암’ 변수와 ‘카메라’ 변수 선언 - ‘오너 캐릭터, Attachment, DoAction’을 매개변수로 받는 임의의 BeginPlay 함수 선언
    //header
    USTRUCT()
    struct FAimData
    {
    	GENERATED_BODY()
    
    public:
    	UPROPERTY(EditAnywhere)
    		float TargetArmLength = 100; //스프링 암 타깃 암 길이 조절 값
    
    	UPROPERTY(EditAnywhere)
    		FVector SocketOffset = FVector(0, 30, 10); //카메라 소켓 오프셋(카메라 생성 위치) 보정값
    
    	UPROPERTY(EditAnywhere)
    		bool bEnableCameraLag; //카메라 렉 활성화 여부 : 움직이면 조금 뒤에 따라가는 모션 설정
    
    	UPROPERTY(EditAnywhere)
    		FVector CameraLocation; //카메라 위치 보정값
    
    };
    
    public:
    	void BeginPlay(class ACharacter* InOwner, class ACAttachment* InAttachment, class UCDoAction* InDoAction) override;
    
    private:
    	class USpringArmComponent* SpringArm;
    	class UCameraComponent* Camera;
    
    private:
    	FAimData OriginData; //원본 데이터 저장
    
    • CPP 파일 - 임의의 BeginPlay 함수 정의 - 부모 함수 호출 - ‘스프링 암’과 ‘카메라’의 컴포넌트를 ‘오너 캐릭터’에서 가져온다. - ‘누름’ 함수 확인 - ‘스프링 암’과 ‘카메라’ 변수의 값이 없으면 실행하지 않는다. - ‘땜’ 함수 확인 - ‘스프링 암’과 ‘카메라’ 변수의 값이 없으면 실행하지 않는다.
    //CPP
    void UCSubAction_Bow::BeginPlay(ACharacter* InOwner, ACAttachment* InAttachment, UCDoAction* InDoAction)
    {
    	Super::BeginPlay(InOwner, InAttachment, InDoAction);
    
    	SpringArm = CHelpers::GetComponent<USpringArmComponent>(InOwner);
    	Camera = CHelpers::GetComponent<UCameraComponent>(InOwner);
    }
    
    void UCSubAction_Bow::Pressed()
    {
    	CheckNull(SpringArm);
    	CheckNull(Camera);
    
    	Super::Pressed();
    
    }
    
    void UCSubAction_Bow::Released()
    {
    	CheckNull(SpringArm);
    	CheckNull(Camera);
    
    	Super::Released();
    }
    

서브 엑션 별개 설정

  • 서브 엑션은 현재 상태와는 무관하게 동작하는 기능이다.
    • 워프 중 시점 변환 / 조준 중 발사 등
  • 모든 게임의 원본 시야각은 ‘90’으로 설정되어있다.
    • 가로 세로 비율에서 ‘세로가 1일때’ ‘90도’를 맞춰놓는다.
  • CStateComponent
    • 헤더 파일 - 서브 엑션 중인지 확인하기 위해서 ‘서브 엑션 확인’ 변수 선언 - ‘서브 엑션 모드 활성’ 함수 선언 - ‘서브 엑션 모드 비활성’ 함수 선언 - 외부에서 서브엑션중인지 확인하기 위해 ‘서브 엑션 확인’ 함수 선언하고 ‘서브 엑션 확인 변수’ 반환으로 정의한다.
    //header
    FORCEINLINE bool IsSubActionMode() { return bInSubActionMode; }
    
    void OnSubActionMode();
    void OffSubActionMode();
    
    private:
    	bool bInSubActionMode; //서브엑션은 아이들모드와 별개로 작동한다.
    
    • CPP 파일 - ‘서브 엑션 활성’ ‘서브 엑션 비활성’ 함수는 ‘서브 엑션 모드중 확인’ 변수를 true, false 설정으로 저장한다.
    //CPP
    void UCStateComponent::OnSubActionMode()
    {
    	bInSubActionMode = true;
    }
    
    void UCStateComponent::OffSubActionMode()
    {
    	bInSubActionMode = false;
    }
    
  • CSubAction_Bow
    • CPP 파일 - ‘누름’ 함수 확인 - ‘원본 데이터’의 ‘타겟 암 길이’에 ‘스프링 암’의 ‘타겟 암 길이’를 저장한다. - ‘원본 데이터’의 ‘소켓 오프셋’에 ‘스프링 암’의 ‘소켓 오프셋’를 저장한다. - ‘원본 데이터’의 ‘카메라 렉 활성화 확인’에 ‘스프링 암’의 ‘카메라 렉 활성화 확인’를 저장한다. - ‘원본 데이터’의 ‘카메라 위치’에 ‘카메라’의 ‘상대적 위치 가져오기’를 저장한다. - ‘스프링 암’의 ‘타겟 암 길이에 ‘에임 데이터’의 ‘타겟 암 길이’를 저장한다. - ‘스프링 암’의 ‘소켓 오프셋’에 ‘에임 데이터’의 ‘소켓 오프셋’을 저장한다. - ‘스프링 암’의 ‘카메라 렉 활성화 확인’에 ‘에임 데이터’의 ‘카메라 렉 활성화 확인’을 저장한다. - ‘카메라’의 ‘상대적 위치 설정’ 함수에 ‘에임 데이터’의 ‘카메라 위치’를 넣어 호출한다. - ‘카메라’의 ‘FOV’를 45로 설정한다. - ‘땜’ 함수 확인 - ‘스프링 암’의 ‘타겟 암 길이에 ‘원본 데이터’의 ‘타겟 암 길이’를 저장한다. - ‘스프링 암’의 ‘소켓 오프셋’에 ‘원본 데이터’의 ‘소켓 오프셋’을 저장한다. - ‘스프링 암’의 ‘카메라 렉 활성화 확인’에 ‘원본 데이터’의 ‘카메라 렉 활성화 확인’을 저장한다. - ‘카메라’의 ‘상대적 위치 설정’ 함수에 ‘원본 데이터’의 ‘카메라 위치’를 넣어 호출한다. - ‘카메라’의 ‘FOV’를 90으로 설정한다.
    //CPP
    void UCSubAction_Bow::BeginPlay(ACharacter* InOwner, ACAttachment* InAttachment, UCDoAction* InDoAction)
    {
    	Super::BeginPlay(InOwner, InAttachment, InDoAction);
    
    	SpringArm = CHelpers::GetComponent<USpringArmComponent>(InOwner);
    	Camera = CHelpers::GetComponent<UCameraComponent>(InOwner);
    }
    
    void UCSubAction_Bow::Pressed()
    {
    	CheckNull(SpringArm);
    	CheckNull(Camera);
    
    	Super::Pressed();
    
    	State->OnSubActionMode();
    
    	OriginData.TargetArmLength = SpringArm->TargetArmLength;
    	OriginData.SocketOffset = SpringArm->SocketOffset;
    	OriginData.bEnableCameraLag = SpringArm->bEnableCameraLag;
    	OriginData.CameraLocation = Camera->GetRelativeLocation();
    
    	SpringArm->TargetArmLength = AimData.TargetArmLength;
    	SpringArm->SocketOffset = AimData.SocketOffset;
    	SpringArm->bEnableCameraLag = AimData.bEnableCameraLag;
    	Camera->SetRelativeLocation(AimData.CameraLocation);
    
    	Camera->FieldOfView = 45; //시야각 설정 (실제 시야각의 반이다. => 45도)
    
    }
    
    void UCSubAction_Bow::Released()
    {
    	CheckNull(SpringArm);
    	CheckNull(Camera);
    
    	Super::Released();
    
    	State->OffSubActionMode();
    
    	SpringArm->TargetArmLength = OriginData.TargetArmLength;
    	SpringArm->SocketOffset = OriginData.SocketOffset;
    	SpringArm->bEnableCameraLag = OriginData.bEnableCameraLag;
    	Camera->SetRelativeLocation(OriginData.CameraLocation);
    
    	Camera->FieldOfView = 90; //시야각 설정 (원래 시야각 : 90도)
    }
    

블렌드 스페이스와 에임 오프셋 차이점

  • 블렌드 스페이스 : 핀에 연결하는 값이 첫 시작 값이다.
  • 에임 오프셋 : 기준 애니메이션과 핀에 연결한 값이 섞이는 값이 첫 시작 값이다.

'공부 > Unreal' 카테고리의 다른 글

24.08.22  (0) 2024.08.24
24.08.21  (3) 2024.08.23
24.08.19  (0) 2024.08.20
24.08.16  (0) 2024.08.20
24.08.13  (0) 2024.08.16