UE5 Issues : 총기 스폰 및 포인터

2025. 2. 27. 22:09·Unreal Engine

이번 글의 주제는 인벤토리에 가지고 있는 총기와 현재 장착하고 있는 총기를 연동하는 방식에 대한 내용이다.

 

1. 전체적인 로직


UI의 동작

  • 왼쪽은 무기를 획득하기 전에 모습이다. 이때는 UI의 버튼을 클릭하여도 아무 일도 발생하지 않는다.
  • 오른쪽은 무기를 획득한 후의 모습이다.
    • 무기는 각자 고유한 int32 변수를 가지고 있어, 어떤 무기인지 식별할 수 있게 하였다.
    • 무기를 획득하게 되면, GameInstance가 가지고 있는 TArray<int32> WeaponInventoryItem; 에 해당 인덱스를 저장하게 된다.
    • UI 에서는 (GameState) 해당 인덱스를 체크해서, 존재하는 인덱스라면 오른쪽 처럼 UI에 존재하는 이미지의 투명도를 1로 만들어 보이게 해준다.
    • 이후 투명도가 1인 버튼은 클릭이 가능하게 되고, 클릭하는 순간 EquipWeaponBack 함수를 call하게 된다.

 

캐릭터의 동작

  • 캐릭터는 CurrentWeapon이라는 현재 장착한 무기에 대한 정보와 TempWeapon이라는 임시 무기를 가지고 있다.

EquipWeaponBack 의 동작

  • 위에서 버튼이 클릭된 경우 해당 함수가 call되게 되는데 이때 캐릭터의 변수인 TempWeapon에 해당하는 인덱스의 무기를 spawn하게 된다.
  • 이후 CurrentWeapon이 존재하면 swap을 해주고
  • 없다면 CurrentWeapon = TempWeapon을 통해 로직을 구성했다.

 

 

2. 문제점


이 방식은 계속해서 무기를 spawn하기 때문에 아래와 같을 시점에서 버그가 생기게 된다.

  • 무기(A)를 10발 쏘고 장전이 안된 상태로 다른 무기(B)로 교체
  • 다른 무기(B)를 쏘고 다시 무기(A)로 교체하면, 무기(A)의 총알이 모두 장전된 상태가 된다.
    • 이유는 무기 자체적으로 Total Ammo와 Current Ammo가 있는데, Current Ammo는 Total Ammo인 상태로 만들었기 때문이다.
  • 즉, 기존의 무기가 가지고 있는 정보를 저장하는 것이 아니라 새롭게 생성하기 때문이다.

(글을 쓰면서 갑자기 든 생각은 우리가 무기를 획득했을 때 장전이 안되어 있는 것이 맞는 것 같기도 하다..)

 

 

3. 해결책


캐릭터에 새로운 변수인 TMap<int32, AWeapon*> PlayerWeaponInventory; 를 가지게 하였다.

이 변수가 무기 포인터를 가지고 있게 해서 Current Weapon과 Swap하도록 만들기 위해서 였다.

 

EquipWeaponBack 수정 버전

  • 만약 해당 인덱스에 해당하는 무기가 없다면 새롭게 spawn해서 PlayerWeaponInventory에 넣어주기
  • 장착된 무기가 없는 경우 Current Weapon을 바로 새로 스폰한 무기로 교체
  • 장착된 무기가 있는 경우 기존에 장착한 무기의 정보를 가져와서 현재 게임에서 보이지 않게 만들고, 장착하고자 하는 무기를 PlayerWeaponInventory 의 [ ] 연산을 통해 가져와서 게임에서 보이도록 교체하기
더보기
void APlayerCharacter::EquipWeaponBack(int32 WeaponIdx)
{
	//attack animation -> can't change weapon
	if (bIsWeaponEquipped)
		return;

	//timer reset
	GetWorldTimerManager().ClearTimer(FireRateTimerHandle);
	
	//no weapon exist(check by idx) -> spawn
	if (PlayerWeaponInventory[WeaponIdx] == nullptr)
	{
		if (WeaponIdx == 1)
		{
			PlayerWeaponInventory[WeaponIdx] = GetWorld()->SpawnActor<AWeaponAR1>();
		}
		else if (WeaponIdx == 2)
		{
			PlayerWeaponInventory[WeaponIdx] = GetWorld()->SpawnActor<AWeaponAR2>();
		}
		else if (WeaponIdx == 3)
		{
			PlayerWeaponInventory[WeaponIdx] = GetWorld()->SpawnActor<AWeaponSR>();
		}
		else if (WeaponIdx == 4)
		{
		}	
	}

	if (IsValid(CurrentWeapon))
	{
		TObjectPtr<AWeapon> Temp = PlayerWeaponInventory[WeaponIdx];
		int32 Idx = CurrentWeapon->GetWeaponNumber();
		PlayerWeaponInventory[Idx] = CurrentWeapon;
		PlayerWeaponInventory[Idx]->SetActorHiddenInGame(true);
		CurrentWeapon = Temp;
		CurrentWeapon->SetActorHiddenInGame(false);
	}	
	else
	{
		CurrentWeapon = PlayerWeaponInventory[WeaponIdx];
	}

	CurrentWeapon->SetActorEnableCollision(false);
	FName WeaponSocket(TEXT("back_socket"));
	CurrentWeapon->AttachToComponent(GetMesh(), FAttachmentTransformRules::SnapToTargetNotIncludingScale, WeaponSocket);
	bIsWeaponEquippedBack = true;
}

 

 

4. 추가


처음에 TMap<int32, AWeapon*> PlayerWeaponInventory 타입을 사용하게 된 이유는 CurrentWeapon이라는 변수와 바꿔가면서 구현하면 될 것이라고 생각했지만, 이 방식은 이전의 무기가 계속해서 보이는 문제점이 있었다.

 

이전의 무기에 대한 정보를 저장하면서 무기는 보이지 않게 하는 방법은 SetActorHiddenInGame 함수를 쓰는 방법이 최선일 것 같다고 생각하여, 해당 방식을 사용해서 구현했다.

'Unreal Engine' 카테고리의 다른 글

Unreal Engine - TSubclassOf & StaticClass  (0) 2025.02.27
Unreal Engine - 총기 반동, 데칼, 탄피 효과  (0) 2025.02.27
UE5 Issues : 인벤토리 UI  (0) 2025.02.26
UE5 Issues : 캐릭터 아이템 획득 로직 구현  (0) 2025.02.24
UE5 Issues : Enhanced Input (Triggered & Started)  (0) 2025.02.23
'Unreal Engine' 카테고리의 다른 글
  • Unreal Engine - TSubclassOf & StaticClass
  • Unreal Engine - 총기 반동, 데칼, 탄피 효과
  • UE5 Issues : 인벤토리 UI
  • UE5 Issues : 캐릭터 아이템 획득 로직 구현
gbleem
gbleem
gbleem 님의 블로그 입니다.
  • gbleem
    gbleem 님의 블로그
    gbleem
  • 전체
    오늘
    어제
    • 분류 전체보기 (177)
      • Unreal Engine (66)
      • C++ (19)
      • 알고리즘(코딩테스트) (27) N
      • TIL (60)
      • CS (4)
      • 툴 (1)
  • 블로그 메뉴

    • 홈
    • 카테고리
  • 링크

    • 과제용 깃허브
    • 깃허브
    • velog
  • 공지사항

  • 인기 글

  • 태그

    BFS
    상속
    템플릿
    enhanced input system
    gamestate
    addonscreendebugmessage
    Vector
    motion matching
    character animation
    싱글턴
    actor 클래스
    applydamage
    매크로 지정자
    cin함수
    additive animation
    const
    C++
    DP
    map을 vector로 복사
    blend pose
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
gbleem
UE5 Issues : 총기 스폰 및 포인터
상단으로

티스토리툴바