초보 코린이의 성장 일지

UE4 Notify, Attach, Weapon 본문

언리얼

UE4 Notify, Attach, Weapon

코오린이 2023. 4. 28. 18:58

빽스탭 모션을 만들어서 동작이 되지만, 한번밖에 실행되지 않을 것이다. 이유는 Notify가 있지 않기 때문 그래서 하나를 생성해 줄 것이다.

1. 사용할 끝을 나타내는 노티파이 생성.

더보기
#pragma once

#include "CoreMinimal.h"
#include "Animation/AnimNotifies/AnimNotify.h"
#include "Components/CStateComponent.h"
#include "CAnimNotify_EndState.generated.h"

UCLASS()
class U2212_06_API UCAnimNotify_EndState : public UAnimNotify
{
	GENERATED_BODY()
	
private:
	UPROPERTY(EditAnywhere, Category = "Type")
		EStateType StateType;

public:
	FString GetNotifyName_Implementation() const override;

	void Notify(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation) override;
};
#include "CAnimNotify_EndState.h"
#include "Global.h"
#include "Characters/ICharacter.h"

FString UCAnimNotify_EndState::GetNotifyName_Implementation() const
{
	return "EndState";
}

void UCAnimNotify_EndState::Notify(USkeletalMeshComponent * MeshComp, UAnimSequenceBase * Animation)
{
	Super::Notify(MeshComp, Animation);
	CheckNull(MeshComp);
	CheckNull(MeshComp->GetOwner());

	// State를 끝내기 위해서 어떠한 방법으로 판단을 할 것인지 알아야한다.
	IICharacter* character = Cast<IICharacter>(MeshComp->GetOwner());
	CheckNull(character);

	switch (StateType)
	{
		// 빽스텝 실행 후 노티파이로 정지 시키기
		case EStateType::BackStep: character->End_BackStep(); break;
	}
}

1. 노티파이 타입을 판단 후 맞다면 끝을 내준다.


- 하나 알고 넘어가면 좋은 점 -


인터페이스 (가상, 추상, 일반)
1. 원래에 인터페이스는 순수 가상과 함수만을 가지고 있도록 설계되었다. 하지만 그건 객체지향이 정립되기 이전이기 때문
2. 그룹을 묶어주기 위해 사용.
3. 3가지 상속받고 있는 구조에서 하나만이 그 기능을 사용해야 할때 나머지는 그 기능을 사용하면 안될때 그룹으로 묶어서 지정해준다.
4. 서로간에 연결을 위해 사용
 
추상 클래스 (가상, 추상, 일반)
1. 순수 가상 함수를 하나라도 포함한 것
2. 순수 가상 함수를 포함하지 않아도 언리얼에서는 추상을 만들수 있다 방법은 UCLASS에 Abstract를 명시해주면 된다.
3. 모든 기능들이 구현되어 있지만 움직이는 기능만은 없는 상태.

구조체와 Class에 차이
1. 접근 지정자 차이 (Class는 Private, Struct는 Public)
2. 선언할때의 차이 즉 이름.
3. 지금의 구조체와 Class에 차이는 없어지고 동일하게 판단한다.

일반 클래스와 추상 클래스에 차이
1. 일반 클래스는 객체화 될 수 있지만, 추상 클래스는 객체화 될 수 없다.


1. 선택 아래에 설명을 보면 UObject라고 쓰여져 있지만, UObject를 상속받아서 다른 UObject 기반 클래스에 구현해야 한다.

2. Character에 기능을 다 몰아서 담아두기 위해 이름을 Character로 만들어줬다.

더보기
#pragma once

#include "CoreMinimal.h"
#include "UObject/Interface.h"
#include "ICharacter.generated.h"

// 인터페이스 직렬화를 위한 기본코드 이므로 수정하면 안된다.
UINTERFACE(MinimalAPI)
class UICharacter : public UInterface
{
	GENERATED_BODY()
};

// 작업할 공간.
class U2212_06_API IICharacter
{
	GENERATED_BODY()

public:
	// 자식에서 의무적으로 구현하게되면 순수 가상 함수로(추상) 들어가지만,
	// 아니라면 일반 가상 함수로 들어간다.
	virtual void End_BackStep() {}
};
#include "Characters/ICharacter.h"

1. 인터페이스 선언.


더보기
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "Components/CStateComponent.h"
#include "Characters/ICharacter.h"
#include "CPlayer.generated.h"

UCLASS()
class U2212_06_API ACPlayer 
	: public ACharacter
	, public IICharacter // 다중 상속 (언리얼에서 다중 상속 가능)
{
	GENERATED_BODY()
    
public:
	void End_BackStep() override; // 인터페이스 사용.
};
#include "Characters/CPlayer.h"
#include "Global.h"
#include "CAnimInstance.h"
#include "GameFramework/SpringArmComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Camera/CameraComponent.h"
#include "Components/SkeletalMeshComponent.h"
#include "Components/InputComponent.h"
#include "Components/CMontagesComponent.h"
#include "Components/CMovementComponent.h"

void ACPlayer::End_BackStep()
{
	Movement->DisableControlRotation(); // 카메라 반대로 뒤집어 주기.

	State->SetIdleMode(); // Idle 모드로 돌려주기
}

1. 다중 상속을 먼저 받아준다.

2. Player로 와서 인터페이스 등록해주고, 그 안에 행동을 넣어준다.

1. 몽타주에 들어가 노티파이 배치해주고, State Type 설정해준다.

2. 이제 한번만 빽스탭하고 끝나는게 아닌 노티파이가 들어가서 계속 키를 누르면 실행할 수 있다.


1. 무기를 장착시켜주기 위해 생성.

더보기
#pragma once

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

UCLASS()
class U2212_06_API ACAttachment : public AActor
{
	GENERATED_BODY()
	
protected:
	// 블루프린트에서 접근 가능, 컴포넌트기 때문에 VisibleAnywhere 붙인다.
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
	// 어느곳에 붙을지 모르기 때문에 USceneComponent Root 기준으로 잡는다.
		class USceneComponent* Root;

public:	
	ACAttachment();

protected:
	virtual void BeginPlay() override;

protected:
	// BP 자식에서 Owner에 접근할수도 있기 때문에 BlueprintReadOnly
	UPROPERTY(BlueprintReadOnly, Category = "Game")
		class ACharacter* OwnerCharacter;
};
#include "Weapons/CAttachment.h"
#include "Global.h"
#include "GameFramework/Character.h"
#include "Components/SceneComponent.h"

ACAttachment::ACAttachment()
{
	CHelpers::CreateComponent(this, &Root, "Root");
}

void ACAttachment::BeginPlay()
{
	// BP에서 BeginPlay이 먼저 호출되면 터진다.
	// 먼저 세팅 후 부모를 불러줘야한다.
	OwnerCharacter = Cast<ACharacter>(GetOwner());

	Super::BeginPlay();
}

1. BP에서 접근할 수 있도록 만들어준다.

2. 부모 BeginPlay 보다 세팅이 먼저 이뤄져야한다.

1. 블루프린트 클래스를 만들어 준다.

1. 처음 들어가면 만들어 놓은 Root가 있을 것이다.

2. SkeletalMesh를 추가해주고, 메시안에 Sword를 설정해준다.


1. 데이터 테이블을 관리할 기능을 담당할 것이다.

 


더보기
#pragma once

#include "CoreMinimal.h"
#include "Engine/DataAsset.h"
#include "CWeaponAsset.generated.h"

UCLASS()
class U2212_06_API UCWeaponAsset : public UDataAsset
{
	GENERATED_BODY()
	
private:
	// 직렬화
	UPROPERTY(EditAnywhere)
	// 객체를 스판시킨다.
		TSubclassOf<class ACAttachment> AttachmentClass;

public:
	// 생성된걸 return 해주기 위해
	FORCEINLINE class ACAttachment* GetAttachment() { return Attachment; }

public:
	UCWeaponAsset();

	// 외부에서 BeginPlay일때 콜해주기 위해 이름을 알기 쉽도록 만들어줬다.
	void BeginPlay(class ACharacter* InOwner);

private:
	// UObject로부터 상속을 받았기 때문에 생명주기로 관리를 받지 않는다.
	// 그래서 가비지 컬렉터가 조금이라도 사용을 하지 않는다고 판단하면, 임의로 제거시켜버린다.
	// 직렬화를 넣어주게 되면, 직렬화된 상태로 판단하고 가비지 컬렉터가 사용자가 제거하기 전까지 물고 있어주기 때문에 제거되지 않는다.
	UPROPERTY()
		class ACAttachment* Attachment;
};
#include "Weapons/CWeaponAsset.h"
#include "Global.h"
#include "CAttachment.h"
#include "GameFramework/Character.h"

UCWeaponAsset::UCWeaponAsset()
{
	// 기본값으로 StaticClass를 넣어준다.
	AttachmentClass = ACAttachment::StaticClass();
}

void UCWeaponAsset::BeginPlay(ACharacter * InOwner)
{
	if (!!AttachmentClass)
	{
		FActorSpawnParameters params;
		params.Owner = InOwner;

		// 선택이 되어있다면 붙여주기.
		Attachment = InOwner->GetWorld()->SpawnActor<ACAttachment>(AttachmentClass, params);
	}
}

 

1. 무기를 Attach 시켜주기 위해 작업.

2. 제거하지 못하도록 직렬화 시켜준다.

 

1. 만들어준 클래스 선택해서 생성.

2. Class 기본값이 None되면 안되기 때문에, 기본값으로 지정해서 넣어준다. (다른 이가 작업을할때 문제가 될 수 있는걸 막아주기 위해 설정)

3. 사용할 Sword를 넣어준다.

 

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

 

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

UE4 Equip, DoAction  (2) 2023.05.04
UE4 Weapon Attach, Sword Equip  (0) 2023.05.01
UE4 Component, BackStep  (0) 2023.04.27
UE4 Tool Bar, Player  (0) 2023.04.26
UE4 Button Command, Icon  (0) 2023.04.25
Comments