공부/Unreal

24.07.19

월러비 2024. 7. 26. 13:09
  • 무기는 실무에서는 ‘조합 객체’로 만든다.
    • 이렇게 객체 하나하나 만들지 않는다.
  • Linear InterPolation : 0 ~ 1까지 어떤 값 ~~
  • TODO 리스트 확인법 : 보기 - 작업 목록
    • //TODO : 할일 목록 작성 → 이렇게 작성한다.
    • 작업 목록에서 이동하고 싶은 작업목록 더블클릭 하면 해당 작업목록으로 이동한다.

무기 설정 예제 - 검

캡슐 컴포넌트 설정

  • cpp 파일 - 위치 ‘ 회전값 ‘ 캡슐 높이 ‘ 캡슐 둘레 설정
//cpp
//캡슐 컴포넌트 설정
Capsule->SetRelativeLocation(FVector(-12, -130, 0));
Capsule->SetRelativeRotation(FRotator(0, 0, 90));
Capsule->SetCapsuleHalfHeight(220); //절반 높이
Capsule->SetCapsuleRadius(11); //둘레

캡슐 컴포넌트 충돌 델리게이트 연결

  • 헤더 파일 - 델리게이트 함수에 연결할 ‘충돌 함수’ 선언 - 델리게이트 파라미터 확인 - cpp 파일 - 캡슐 컴포넌트에 ‘델리게이트 함수’ 연결 : 선언한 충돌함수를 직접 연결한다.
//header
public:
	UFUNCTION()
		void OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);

//cpp
Capsule->OnComponentBeginOverlap.AddDynamic(this, &ACSword::OnBeginOverlap);

플레이어 캐릭터 무기 설정 예제 - 검

  • 블프에서는 이곳 저곳에 있는 타깃들을 가져와서 연결할 수 있지만, C에서는 클래스 마다의 역할을 철저하게 지킨다.
    • 블프 : 오너 가져오기 - 오너를 플레이어로 형변환 - 타깃 : 검 가져오기 - 타깃 : 캡슐 가져오기 - 충돌체 활성화
    • C : Sword에 있는 캡슐을 설정한다.
      • 즉, 해당 객체를 중심으로 외부에서 그 객체에 명령을 내리는 식으로 진행한다.
      • 검에 충돌체 활성화 명령을 정의하고, 외부(플레이어)에서 검 객체에 충돌체 활성화 함수 호출 명령을 내려서 실행하게 된다.
  • 변수는 외부에서 호출해서 사용하다가 값이 바뀌게되면 추적하기가 힘들어지므로, ‘함수’에서 호출해서 사용한다.
  • BlueprintNativeEvent가 나오면 걔네를 상속받는 자식(즉, 생성한 노티파이 스테이트 클래스)에서 Implementable 을 해주면 된다.
    • 자신을 상속받은 자식도 정의할 수 있게하는 기능이다.
      • 이때, 부모에게 ‘virtual’ 키워드가 없더라도, BlueprintNativeEvent 이기 때문에 상속받은 자식에서 정의하므로 ‘override’ 키워드를 붙여줘야한다.
    • 상속한 클래스 내부를 확인해서 사용하고 정의할 함수를 확인한다.
      • 이때, 함수가 포함된 ‘접근지정자’가 없다면 기본적으로 ‘private’다.
  • BlueprintImplementableEvent : 호출은 C에서 할테니까, 필요하면 블루프린트에서 정의하라는 기능이다.
    • 즉, ‘재정의’는 C에서 하는것이 아니라 블프에서 하라는 것이다.
    • 밑으로 내려가면 C에서 재정의하여 사용할 수 있는 비슷한 이름의 함수가 나온다. - 그걸 쓰면 된다.

무기 소환 - 홀스터

  • 헤더 파일 - 무기 - 무기 : 검 클래스 자료형 변수 선언 - cpp 파일 - 무기를 소환할 함수의 설정을 맡는 자료형 선언 - 현재 클래스를 소유한 주체 저장 - 현재 월드에서 ‘액터 스폰’ 함수 호출 : 검 자료형으로 ‘검 클래스 포인터와 파라미터’를 받아서 전체 코드를 무기 변수에 저장한다. - 검 변수에서 ‘컴포넌트에 액터 붙이기’ 함수 호출
//header
private:
	class ACSword* Sword;
	
//cpp
//스폰 액터 조건 설정 자료형
FActorSpawnParameters params;
params.Owner = this;

//검 소환 및 붙이기
Sword = GetWorld()->SpawnActor<ACSword>(ACSword::StaticClass(), params);
Sword->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true) , "Holster_Sword");

무기 장착 애니메이션 하나로 합치기 예제 - 검

  • 무기 장착 애니메이션 중 하나 우클릭 - 생성 - ‘애님몽타주 생성’ 클릭 - 연결할 애니메이션을 생성한 몽타주로 드래그

무기 장착 액션 맵 연결 - 검

  • 헤더 파일 - 검 액션 함수 선언 - 무기 장착 함수 선언 - ‘장착 확인’ 변수 선언 - ‘무기 장착 중 확인’ 변수 선언 - 무기 : 검 장착 애니메이션 몽타주 클래스 자료형 변수 선언 - cpp 파일 - 액션 맵 연결 : 검 액션 함수 연결 - 검 액션 함수 정의 - 무기가 장착되었는지 확인하고 ‘장착중 : 장착해제’ 와 ‘비 장착중 : 장착’으로 나눈다. - 장착하기 않았다면 ‘무기 장착 함수’를 호출한다. - ‘무기 장착 함수’ 정의 - 현재 무기를 장착 행동을 하는 중인지 확인 - ‘무기 장착 행동 중’을 체크한다. - ‘무기 : 검 장착 애니메이션 몽타주’가 있는지 확인하고 ‘애니메이션 몽타주 실행’ 함수를 호출한다.
//header
private:
	UPROPERTY(EditAnywhere, Category = "Sword")
		class UAnimMontage* EquipMontage; //장착 애니메이션
		
	UPROPERTY(EditAnywhere, Category = "Sword")
		class UAnimMontage* ComboMontages[3]; //검 공격 애니메이션 3개
		
private:
	void OnSword();

private:
	void Equip();
	
private:
	bool bEquipped;
	bool bEquipping;
	
//cpp
PlayerInputComponent->BindAction("Sword", EInputEvent::IE_Pressed, this, &ACPlayer::OnSword);

if (bEquipped)
	{
		UnEquip();

		return;
	}

	Equip();
	
	CheckTrue(bEquipping);

	bEquipping = true;

	if (!!EquipMontage)
	{
		PlayAnimMontage(EquipMontage, 2);
	}

애님 노티파이 스테이트 클래스 생성

  • C++ 클래스 생성 - 모든 클래스 - AnimNotifyState 검색

애님 노티파이 스테이트 설정 - 장착

  • 함수의 파라미터를 확인하기 위해 상속받은 부모로 올라가서 사용할 함수를 찾아야한다.,
    • ‘재정의 가능’한지 여부, ‘C에서 사용할 수 있는 함수’인지 여부, ‘파라미터가 있는지’ 여부를 확인해야한다.
  • 헤더 파일 - 노티파이 이름 재정의 함수 선언 - 노티파이 시작 ‘ 끝 재정의 함수 선언 - cpp 파일 - 노티파이 이름 가져오기 함수 재정의 - 원하는 이름 써서 반환한다. - 노티파이 시작 함수 재정의 - 부모의 기능을 사용할 함수이니 ‘Super’ 키워드를 작성한다. - ‘메쉬 컴포넌트’와 ‘메쉬 컴포넌트의 주체(오너)’가 있는지 확인한다. - 애니메이션을 플레이하는 주체는 ‘플레이어’이니 ‘플레이어 형변환’이 가능하므로, ‘플레이어 형변환’을 진행한다. - 플레이어가 비어있는지 확인한다. - 플레이어에 있는 ‘장착 시작 함수’를 호출한다. (이게 외부에서 호출한다는 것이다.) - 노티파이 끝 함수도 재정의한다. - 플레이어 헤더 파일 - ‘무기 장착 시작 함수’ 선언 - 플레이어 cpp 파일 - ‘무기 장착 시작 함수’ 정의 - 무기를 ‘손 소켓’에 붙이는 함수 호출 ⇒ ‘장착 종료’도 ‘장착 시작’과 같은 방식으로 진행한다.
//노티파이 스테이트 header
private:
	FString GetNotifyName_Implementation() const override;

	void NotifyBegin(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, float TotalDuration, const FAnimNotifyEventReference& EventReference) override;
	void NotifyEnd(USkeletalMeshComponent* MeshComp, UAnimSequenceBase* Animation, const FAnimNotifyEventReference& EventReference) override;
	
//노티파이 스테이트 cpp
return "Equip";

Super::NotifyBegin(MeshComp, Animation, TotalDuration, EventReference);
CheckNull(MeshComp);
CheckNull(MeshComp->GetOwner());

ACPlayer* player = Cast<ACPlayer>(MeshComp->GetOwner());
CheckNull(player);

player->Begin_Equip();

//플레이어 header
public:
	void Begin_Equip();
	
//플레이어 cpp
Sword->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), "Hand_Sword");

bEquipping = false;
bEquipped = true;

Movement->EnableControlRotation();

애니메이션에 노티파이 추가하기

  • 몽타주 파일 - 트랙에서 우클릭 - 노티파이 스테이트 추가 - 생성한 노티파이 스테이트 클래스 파일 탐색

애니메이션 ‘방향’ 설정

  • 애니메이션 헤더 - 방향 변수 선언 - cpp 파일 - 방향 변수에 ‘방향 계산 함수’를 ‘속도와 마우드 회전값’을 받아 호출한다.
//header
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
		float Direction;
		
//cpp
Direction = CalculateDirection(OwnerCharacter->GetVelocity(), OwnerCharacter->GetControlRotation());

무기 장착 되었는지 여부 확인해서 무기 장착 및 해제 동작 실행 - 코드 및 블루프린트

  • Linear InterPolation (선형 보간) : 어떤 값을 0 ~ 1까지 갈때 어떤 값을 취할지 선택하는 기법이다.
    • Lerp 라고 많이 부른다.
    • A (1, 0, 0) / B (0, 0, 1)
    • (1 - t) * A + t * B
    • t = 0 → (1, 0, 0)
    • t = 1 → (0, 0, 1)
    • t = 0.5 → (0.5, 0, 0.5)
    • 즉, t 값이 커질수록 값도 커지는 방식이다.
    • 애니메이션 보간 식도 따로 지정하지 않은 이상, 기본값은 ‘선형 보간’ 이다.
  • 플레이어 헤더 파일 - ‘장착 된지 확인하는 변수 가져오기’ 함수 선언 및 초기화 - 애니메이션 헤더 파일 - ‘무기 장착 됨’ 변수 선언 및 블루프린트 사용 매크로 지정 - 애니메이션 cpp 파일 - 애니메이션의 오너 캐릭터를 가져와 형변환하고 비어있는지 체크한다. - 오너캐릭터에 있는 ‘무기 장착됨’ 함수를 가져와 저장한다.
//player header
public:
	//이 함수는 인라인 해서 콜 하라는 의미이다.
	FORCEINLINE bool GetEquipped() { return bEquipped; }

//header
UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Animation")
		bool bEquipped;

//cpp
ACPlayer* player = Cast<ACPlayer>(OwnerCharacter);
CheckNull(player);

bEquipped = player->GetEquipped();
  • 애니메이션 블루프린트 - ‘검 포즈’ 캐시 사용 - ‘무기 장착됨’ 변수 검색 - 핀 끌고 ‘부울로 포즈 블렌딩’ 검색 - ‘무기 장착됨’이 true 일때 ‘검 포즈’ 가 나오니 ‘True 포즈’에 ‘검 포즈’를 연결하고, ‘False 포즈’에 ‘무기 장착 안함 포즈’를 연결한다.

무기 장착 해제

  • 플레이어 헤더 파일 - 장착 해제 함수 선언 - ‘검 장착 함수’ 에서 이미 장착되었을때 ‘장착 해제’ 함수를 호출하도록 한다. - ‘장착 해제’ 함수 정의 - 무기의 위치를 ‘손 소켓’ 으로 변경한다. - ‘장착 됐음’을 false로 변경한다. - ‘무브먼트 컴포넌트’의 ‘마우스 회전 사용 안함’ 함수를 호출한다.
//header
private:
	void UnEquip();
	
//cpp
if (bEquipped)
{
	UnEquip();

	return;
}

Equip();

Sword->AttachToComponent(GetMesh(), FAttachmentTransformRules(EAttachmentRule::KeepRelative, true), "Holster_Sword");

bEquipped = false;
Movement->DisableControlRotation();

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

24.07.23  (0) 2024.07.27
24.07.22  (0) 2024.07.26
24.07.18  (1) 2024.07.23
24.07.17  (1) 2024.07.23
24.07.15  (1) 2024.07.17