초보 코린이의 성장 일지

UE4 Bow Aim (2) 본문

언리얼

UE4 Bow Aim (2)

코오린이 2023. 7. 7. 12:25

지난 코드작성에 실수한 부분이 하나 있다.

수정 전

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "CSubAction.generated.h"

UCLASS(Abstract) // 기능이 없으므로, 할당 x
class U2212_06_API UCSubAction : public UObject
{
	GENERATED_BODY()

public:
	virtual void Pressed();
	virtual void Released();

public:
	// BP랑 상호연동 가능하도록,
	// BlueprintNativeEvent로 정의하면 Implementation 붙여주기
	UFUNCTION(BlueprintNativeEvent)
		void Begin_SubAction();
	virtual void Begin_SubAction_Implementation() {} // 자식에서 필요한데로 재정의해서 사용

	UFUNCTION(BlueprintNativeEvent)
		void End_SubAction();
	virtual void End_SubAction_Implementation() {}

	UFUNCTION(BlueprintNativeEvent)
		void Tick(float InDeltaTime);
	virtual void Tick_Implementation(float InDeltaTime) {}

protected:
	bool bInAction;
};
#include "CSubAction.h"
#include "Global.h"
#include "GameFramework/Character.h"
#include "Components/CStateComponent.h"
#include "Components/CMovementComponent.h"
#include "Components/CapsuleComponent.h"

void UCSubAction::Pressed()
{
	bInAction = true;

}

void UCSubAction::Released()
{
	bInAction = false;

}

1. Begin_SubAction_Implementation이 아닌 Pressed, Released로 변경해줘야한다.

수정 전 모션
수정 후 모션

1. 모션이 이제 구현한 Aim 모션으로 나오게된다.


1. 활줄을 당길 수 있도록 클래스를 하나 생성해준다.

#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "CAnimInstance_Bow.generated.h"

UCLASS()
class U2212_06_API UCAnimInstance_Bow : public UAnimInstance
{
	GENERATED_BODY()

protected:
	UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
		float Bend; // 활줄이 휘어지게 하는 값

public:
	// 외부에서 세팅하기 위해 반출, 수정도 할 수 있게 const 생략
	// *로 값을 실시간으로 변경하게끔
	FORCEINLINE float* GetBend() { return &Bend; }

public:
	// 애니메이션 돌아가게 하기.
	void NativeBeginPlay() override;
	void NativeUpdateAnimation(float DeltaSeconds) override;

};
#include "Weapons/AnimInstances/CAnimInstance_Bow.h"
#include "Global.h"

void UCAnimInstance_Bow::NativeBeginPlay()
{
	Super::NativeBeginPlay();

}

void UCAnimInstance_Bow::NativeUpdateAnimation(float DeltaSeconds)
{
	Super::NativeUpdateAnimation(DeltaSeconds);

}

1. Bend가 나중에 활줄을 당길때 Curve에서 주었던 값을 변화시킬 것이다.


1. CanimInstance_Bow, Skeleton_ElvenBow를 선택해서 애니메이션 블루프린트를 생성해준다.

1. Bend를 불러서 애니메이션에 연결해준다.

2. Bend값을 수정해 보면, 활줄이 수치만큼 휘어지는걸 확인할 수 있다.

1. 애니메이션을 사용하기 위해 레퍼런스 복사를 우선 해준다.


#pragma once

#include "CoreMinimal.h"
#include "Weapons/CAttachment.h"
#include "CAttachment_Bow.generated.h"

UCLASS()
class U2212_06_API ACAttachment_Bow : public ACAttachment
{
	GENERATED_BODY()
public:
	float* GetBend();

public:
	ACAttachment_Bow();

};
#include "Weapons/Attachments/CAttachment_Bow.h"
#include "Global.h"
#include "Weapons/AnimInstances/CAnimInstance_Bow.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/PoseableMeshComponent.h"

ACAttachment_Bow::ACAttachment_Bow()
{
	PrimaryActorTick.bCanEverTick = true;

	TSubclassOf<UCAnimInstance_Bow> animInstance;
	CHelpers::GetClass<UCAnimInstance_Bow>(&animInstance, "AnimBlueprint'/Game/Weapons/Bow/ABP_ElvenBow.ABP_ElvenBow_C'");
	SkeletalMesh->SetAnimInstanceClass(animInstance); // AnimInstance 생성

}

float* ACAttachment_Bow::GetBend()
{
	// 위에서 생성한 AnimIntance안에 Bend 주소를 return 시켜준다.
	return Cast<UCAnimInstance_Bow>(SkeletalMesh->GetAnimInstance())->GetBend();

}

1. 복사해 놓은 레퍼런스 주소를 넣어줌으로써, 애니메이션을 사용할 수 있게 만들어준다.

2. Bow 활줄을 당기는건 Skeleton으로 만들었다는걸 잊어서는 안된다.

3. 이제 외부에있는 Bend 값을 가져와서 넣어줘야 활줄이 수치만큼 변화되는걸 볼 수 있게 된다.


#pragma once

#include "CoreMinimal.h"
#include "Components/TimelineComponent.h"
#include "Weapons/CSubAction.h"
#include "CSubAction_Bow.generated.h"

UCLASS(Blueprintable)
class U2212_06_API UCSubAction_Bow : public UCSubAction
{
	GENERATED_BODY()

public:
    void BeginPlay(class ACharacter* InOwner, class ACAttachment* InAttachment, class UCDoAction* InDoAction) override;

private:
    UFUNCTION()
        void OnAiming(FVector Output);

private:
    // Attachment_Bow에서 넘겨받을 Bend에 대한 변수를 생성
    float* Bend;

};
#include "Weapons/SubActions/CSubAction_Bow.h"
#include "Components/TimelineComponent.h"
#include "Global.h"
#include "GameFramework/Character.h"
#include "GameFramework/PlayerController.h"
#include "GameFramework/SpringArmComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/CStateComponent.h"
#include "Weapons/Attachments/CAttachment_Bow.h"

void UCSubAction_Bow::BeginPlay(ACharacter* InOwner, ACAttachment* InAttachment, UCDoAction* InDoAction)
{
	Super::BeginPlay(InOwner, InAttachment, InDoAction);

	// 캐스팅
	ACAttachment_Bow* bow = Cast<ACAttachment_Bow>(InAttachment);

	if (!!bow)
		// 주소를 가지고 있으므로, 값만 넣어주면 된다.
		Bend = bow->GetBend();
}

void UCSubAction_Bow::OnAiming(FVector Output)
{
	// 이안에서 타임라인을 콜해주는게 아닌, 이 곳에 설정을 해주고 Tick에서 순간마다 콜을 해줘야한다.
	//CLog::Print(Output, 1);

	Camera->FieldOfView = Output.X;

	if (!!Bend)
		// Y값을 넣어준다 0 ~ 100까지 가는 값이 여기서 진행된다.
		*Bend = Output.Y;

}

1. Attachment_Bow에서 넘겨받은 Bend를 저장해 줄 변수를 만들어준다.

2. 캐스팅해서 확인 후 Bend 값을 포인터로 받아서 값을 변화시켜준다.


#include "Weapons/Attachments/CAttachment_Bow.h"
#include "Global.h"
#include "Weapons/AnimInstances/CAnimInstance_Bow.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/PoseableMeshComponent.h"

ACAttachment_Bow::ACAttachment_Bow()
{
	PrimaryActorTick.bCanEverTick = true;

}

1. Attachment_Bow에 Tick을 실행시켜줘야 Bend값이 변화할때 활 줄이 변화되는걸 확인할 수 있게된다.


https://www.youtube.com/watch?v=MvKVc_GqdJU 

 

'언리얼' 카테고리의 다른 글

UE4 Bow Arrow  (0) 2023.07.13
UE4 Bow Aim Bend  (0) 2023.07.10
UE4 Bow Aim  (0) 2023.07.06
UE4 Weapon Bow  (0) 2023.07.05
UE4 SubAction Around Skill  (0) 2023.07.04
Comments