본문 바로가기

언리얼5/언리얼5 개발

UE 아이템 시스템 (공부 정리)

트리거 박스 구현

루트에 트리거 추가

 - 하위 스태틱 매시

 - 하위 이펙트


트리거 박스 클래스 생성

1. 엑터 ->ItemBox 생성

2. ItemBox 비긴 틱 제거

3. 위 추가할 3가지 객체를 멤버변수 선언

-  UBoxComponent ,UStaticMeshComponent , UParticleSystemCompoent

4. 생성자 오버로딩 ItemBox 초기화

4-1. 멤버변수 데이터 초기화

- CreateDefaultSuboject 함수 사용 매개변수는 생성할 기본서브오브젝트의 이름이다.

4-2. 트리거 매쉬컴포넌트 셋업 

- Trigger->SetCollisionProfileName("내가 생성한 프로파일 트리거") ;

- Mesh->SetStaticMesh(아이템 메쉬 레퍼런스)

4-3. 이펙트 셋업

- Effect->SetTemplate(사용할 이펙트 레퍼런스);

- Effect->bAutoActive = false;

  - 처음 자동 동작을 비활성화한다.

반드시 알아야할 충돌  구현 

1.트리거 박스 크기 조절

Trigger->SetBoxExtent(FVector(40.0f, 42.0f, 30.0f));

 

2. 아이템 충돌 이벤트 시작 시 구독대상 함수 OnOverlapBegin
(구독할 함수는 받드시 언리얼의 관리를 받아야할 대상이기에 UPROPERTY를 사용해야함)

UFUNCTION()
void OnOverlapBegin(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepHitResult);

 

3.언리얼에서 충돌 발생시 호출되는 이벤트 함수 매개변수 인자값(현제 객체,구독함수)

Trigger->OnComponentBeginOverlap.AddDynamic(this, &AABItemBox::OnOverlapBegin);

 

4. 콜리전 비활성화 (트리거가 아닌 주체가 되는 엑터를 대상으로 비활성화)

SetActorEnableCollision(false);

 


무기 아이템 디자인

아이템 데이터 생성

 

1. 아이템 에셋 클래스 상속받은 ItemData 자식 클래스 생성

2. 열거타입으로 아이템 타입 생성

UENUM(BlueprintType, Category = Interactive)
enum class EInteractiveType : uint8
{
	WeaponShop UMETA(DisplayName = "WeaponShop"),
	ItemShop UMETA(DisplayName = "ItemShop"),
	RaidSelector UMETA(DisplayName = "RaidSelector"),
};



//Class

public:
	UPROPERTY(EditAnywhere)
	EInteractiveType interactive;

3. 멤버변수 생성

 - 열거타입 interactive 변수 선언  (카테고리 Weapon , 어디서나 수정가능)

 

무기 아이템 데이터 생성

1. ItemDataClass를 상속받는 WeaponItemData Class 생성

- 멤버변수 생성

- 언리얼스태틱 매쉬 WeaponMesh 변수 선언 (카테고리 Weapon , 어디서나 수정가능)

 

객채 생성

2. 마우스 우클릭 -> Miscellaneous(기타) -> DataAsset-> ItemData (포션)

3. 마우스 우클릭 -> Miscellaneous(기타) -> DataAsset-> WeaponItemData (무기 )

4. 2,3에서 생성된 아이템 에셋 더블클릭 후 데이터 디자인

 

의존성 분리를 위한 설계 

  • 게임 레이어: 게임 로직을 구체적으로 구현하는데 사용 (캐릭터 , 게임모드)
  • 미들웨어 레이어 : 게임에 사용되는 미들웨어 모듈 (UI,아이템, 애니메이션 Ai)
  • 데이터 레이어 게임을 구성하는 기본데이터 (스탯 정보 캐릭터 레벨 테이블)

상위레이어는 하위레이어에 직접 접근이 가능, 하위가 상위 레이어의 접근이 필요한 경우는 인터페이스를 구현하여 간접 접근한다.

 


아이템 사용 

 

 

상위레이어 간접접근을 위한 인터페이스 생성

1. 캐릭터 아이템 인터페이스 클래스 생성

- 테이크 아이템 가상함수 생성

 

2. 캐릭터 클래스 인터페이스 상속

 

3. 아이템 박스 수정

- 멤버변수 아이템 클래스 ObjectPtr로 선언

- 충돌받은 엑터의 테이크 함수 호출

 

4. 케릭터 클래스 델리게이트  FOnTakeItemDelate itemData 정의

 

5. 고유한 델리게이트를 저장,호출하는 구조체 (USTRUCT) 아이템래핑을 구현

 - 멤버변수  FOnTakeItemDelate

 - 생성자 오버로딩 파람(델리게이트에 필요한 인자값) -> 내 멤버변수 함수를 호출한다.

 

6. 캐릭터 클래스 방금 만든 구조체를 컨테이닝하는 가변배열 변수 선언

7. 캐릭터 생성자 오버로딩에서 구조체 배열을 초기화 

(자신이 만든 아이템 데이터기준 , 필요한 함수들을 구현해준다.)

// Item Actions
	TakeItemActions.Add(FTakeItemDelegateWrapper(FOnTakeItemDelegate::CreateUObject(this, &AABCharacterBase::EquipWeapon)));
	TakeItemActions.Add(FTakeItemDelegateWrapper(FOnTakeItemDelegate::CreateUObject(this, &AABCharacterBase::DrinkPotion)));
	TakeItemActions.Add(FTakeItemDelegateWrapper(FOnTakeItemDelegate::CreateUObject(this, &AABCharacterBase::ReadScroll)));

 

8. 아이템 사용 구현 (델리게이트 invoke 방법)

void AABCharacterBase::TakeItem(UABItemData* InItemData)
{
	if (InItemData)
	{
		TakeItemActions[(uint8)InItemData->Type].ItemDelegate.ExecuteIfBound(InItemData);
	}
}

 


 

무기 아이템

1. 캐릭터 클래스 생성자에서 웨폰변수 초기화 붙착될 스켈레톤 소켓이름을 반드시 확인해야한다.

	Weapon = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Weapon"));
	Weapon->SetupAttachment(GetMesh(), TEXT("hand_rSocket"));

 

2. 무기 아이템박스 획득(충돌) 시 구현

void AABCharacterBase::EquipWeapon(UABItemData* InItemData)
{
	UABWeaponItemData* WeaponItemData = Cast<UABWeaponItemData>(InItemData);
	if (WeaponItemData)
	{
		Weapon->SetSkeletalMesh(WeaponItemData->WeaponMesh.Get());
	}
}

소프트 레퍼런싱 최적화

커맨드 명령어 Obj List Class = SkeletalMesh

무기가 없는 상태에서 무기 스켈레톤 정보가 나오는것을 확인할수있다. 사용을 하지않는 상태에서도 하드레퍼런싱으로 무기 데이터를

메모리에 미리 올려놓은것을 확인할수있다. 이것을 SoftObjectPtr로 수정하면 다시 Object List Clas로 확인해보면

무기정보가 나오지않는다 무기정보가 초기에 메모리에 올리지않는것으로 볼수있다.

이렇게 언리얼 소프트레퍼런싱을 사용하여 최적화를 할수있다.

void AABCharacterBase::EquipWeapon(UABItemData* InItemData)
{
	UABWeaponItemData* WeaponItemData = Cast<UABWeaponItemData>(InItemData);
	if (WeaponItemData)
	{
		if (WeaponItemData->WeaponMesh.IsPending())
		{
			WeaponItemData->WeaponMesh.LoadSynchronous();
		}
		Weapon->SetSkeletalMesh(WeaponItemData->WeaponMesh.Get());
	}
}

 

'언리얼5 > 언리얼5 개발' 카테고리의 다른 글

UE Fade 기능 만들기  (2) 2024.04.06
GA 유용한 가상 함수  (0) 2024.03.31
UE Hpbar 만들기  (0) 2024.03.29
UE 헤드업 디스플레이 (공부 정리)  (0) 2024.03.25
UE5 향상된 입력 Unreal C++ 에서 사용방법  (0) 2024.03.22