[Unreal_C++_DarkSoul]#6_기능 구현, Targeting 기능

2022. 12. 10. 15:50· 개인프로젝트
목차
  1.  
  2. [Unreal_C++_DarkSoul]#6_Targeting 기능

 

[Unreal_C++_DarkSoul]#6_Targeting 기능

 

Player 근방의 적들을 인지하고, 선택된 적 객체를 Focusing 하는 기능을 구현합니다. 

포트폴리오 진행 사항을 기록하기 위한 포스팅입니다.

 


 

Overview

 

  1. 먼저, Player 근방의 적 객체들을 인식합니다.
  2. 인식된 적 객체들 중 가장 근거리에 위치한 적 객체를 타게팅합니다.
  3. 타게팅 상태에서 "휠"을 올려 현재 타깃이 된 적 객체를 기준으로 시계 방향으로 타게팅 객체를 변경합니다.
  4. 더불어, "휠"을 내리면 반 시계 방향으로 타게팅 객체를 변경할 수 있습니다.

 

* Blueprint로 개발한 과정과 세부 내용들은 같습니다. 아래 링크들을 참조하세요

 

 

[Unreal_블루프린트]#27_Targeting

[Unreal_블루프린트]#27_Targeting Unreal 블루프린트 개발 중 "타게팅" 구현에 대해 알아보겠습니다. "블루 프린트" 활용에 대한 내용입니다. Targeting 1. Get Trace Target 함수 1. Multi Sphere Trace By Objects 최대 Ra

webddevys.tistory.com

 

 

 

[Unreal_블루프린트]#28_Change Targeting

[Unreal_블루프린트]#28_Change Targeting Unreal 블루프린트 개발 중 "타게팅" 구현에 대해 알아보겠습니다. "블루 프린트" 활용에 대한 내용입니다. Camera Focal Point 1. End Lock On 커스텀 이벤트 생성 2. Tick Loc

webddevys.tistory.com

 

코드

1. FindNearbyActors()

/*****************************************************************************************

	목적:
		Enemy Detection Collider 범위 안에 존재하는 Nearby Enemy들을 찾아냅니다.
	설명:
		1. Nearby Actor가 1명이라도 존재하면, FindTargetEnemy() 함수가 호출됩니다.

******************************************************************************************/

void APlayerCharacter::FindNearbyActors()
{

	TArray<TEnumAsByte<EObjectTypeQuery>> NearbyActors;
	TEnumAsByte<EObjectTypeQuery> PawnObjectType = UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_Pawn);
	NearbyActors.Add(PawnObjectType);
	
	TArray<AActor*> IgnoreActors;
	IgnoreActors.Add(this);
	
	TArray<FHitResult> HitResults;

	// Trace Multi For Objects
	bool Result = UKismetSystemLibrary::SphereTraceMultiForObjects(
		GetWorld(),
		GetActorLocation(),
		GetActorLocation() + 10.f,
		EnemyDetectionMaxRadius,
		NearbyActors,
		false,
		IgnoreActors,
		EDrawDebugTrace::None,
		HitResults,
		true
	);

	// When Enemy Detecetd!
	if (Result == true)
	{
		// TODO	:	Decide Targeting Enemy
		for (const auto& Hit : HitResults)
		{
			if (Cast<AEnemyBase>(Hit.GetActor()) != nullptr)
			{
				NearbyEnemies.AddUnique(Cast<AEnemyBase>(Hit.GetActor()));
			}
		}
		FindTargetEnemy();
	}

}

 

Details

 

  1. UKismetSystemLibrary에서 제공하는 Sphere Trace를 활용합니다.
  2. Sphere Trace에서 Hit이 발생하면 Hit이 발생한 적 객체들을 기억하고, FindTargetEnemy()를 호출합니다!
  3. SphereTrace 함수 위로 작성한 코드들은 Sphere Trace를 위해 필요한 인자들을 준비하는 과정이므로, 생략.

 

2. FindTargetEnemy()

/*****************************************************************************************

	목적:	
		Enemy Detection Collider에 Bouding된 주변 적들과 Player 간의 상대적인 거리 계산합니다.
		최종적으로, Min Distance(최소 거리)을 갖는 Enemy Actor가 Target Enemy로 선정됩니다.
	설명:
		1. A = (Player위치 - Enemy위치) X (Player의 Forward Vector)
		2. Min Distance = Fabs( (Player의 Up Vector) * (A) )
		3. Enemy & Min Distance 조합으로 Map을 생성합니다!

******************************************************************************************/

void APlayerCharacter::FindTargetEnemy()
{
	float MinDistance = 100000.f;

	FVector TempCrossProduct = FVector::ZeroVector;
	float TempDotProduct = 0.f;
	int32 TargetEnemyIndex = -1;

	for (int i=0; i<NearbyEnemies.Num(); i++)
	{
		// Cross + Dot
		TempCrossProduct 
			= FVector::CrossProduct(GetActorForwardVector(), NearbyEnemies[i]->GetActorLocation() - GetActorLocation());
		TempDotProduct 
			= FVector::DotProduct(GetActorUpVector(), TempCrossProduct);

		// Map
		MBoundEnemies.Add(NearbyEnemies[i], TempDotProduct);

		// 최소 값 찾기
		float Distance = fabs(TempDotProduct);
		if (Distance < MinDistance)
		{
			MinDistance = Distance;
			TargetEnemyIndex = i;
		}
	}

	if (TargetEnemyIndex != -1)
	{
		TargetEnemy = NearbyEnemies[TargetEnemyIndex];
		CheckNull(TargetEnemy);
	}

}

 

Details

 

  1. 미리 저장한 근방 적 객체들과 Player간의 거리를 계산합니다. 계산 방법은 위 링크들을 살펴보세요
  2. 각 객체를 "Key"로, Player 까지의 거리를 "Value"로 Pair를 생성하고, Map 컨테이너에 삽입합니다.
  3. 결과적으로, 최단 거리에 존재하는 적 객체를 "Target Enemy"로 설정하고 마칩니다.

 

3. CycleClockwise()

/*****************************************************************************************

	목적:
		Enemy Detectio Collider 내부에 위치한 Nearby Actor를 "시계 방향"으로 순회합니다.
	설명:
		1. 현재 Target Enemy로 설정된 Actor는 제외합니다.
		2. 현재 Target Enemy의 Key 값보다 큰 거리 값 중 가장 작은 수를 찾습니다.

******************************************************************************************/

void APlayerCharacter::CycleClockwise()
{

	if (TargetingLockOn == true)
	{
		// TODO	:	양수 중 최소 값 찾기	
		float MinDistance = 100000.f;
		AEnemyBase* TmpEnemy = TargetEnemy;
		for (const auto& pair : MBoundEnemies)
		{
			// #1. Target Enemy 제외
			if (pair.Key == TargetEnemy) continue;

			// #2. 현 Target Enemy 거리보다 큰 거리 값 중 최소 
			if (pair.Value > *MBoundEnemies.Find(TargetEnemy)
				&& pair.Value < MinDistance)
			{
				MinDistance = pair.Value;	
				TmpEnemy = pair.Key;
			}
		}

		CheckNull(TmpEnemy);
		TargetEnemy = TmpEnemy;

	}

}

 

Details

 

  1. 미리 준비한 Map 컨테이너를 통해 다음으로 짧은 거리를 갖는 적 객체를 탐색합니다.
  2. 이때,  시계 방향으로 회전하기 위해서 "음수" 값을 갖는, 즉 반 시계 방향에 위치한 적 객체들은 무시합니다.
  3. 결과적으로, "양수" 거리 값을 갖는 적 객체들 중 현 타깃 다음으로 가까운 적을 타깃으로 설정합니다.

 

3. CycleAntiClockwise()

/*****************************************************************************************

	목적:
		Enemy Detectio Collider 내부에 위치한 Nearby Actor를 "반 시계 방향"으로 순회합니다.
	설명:
		1. 현재 Target Enemy로 설정된 Actor는 제외합니다.
		2. 현재 Target Enemy의 Key 값보다 작은 거리 값 중 가장 큰 수를 찾습니다.

******************************************************************************************/

void APlayerCharacter::CycleAntiClockwise()
{
	if (TargetingLockOn == true)
	{
		// TODO	:	음수 중 최대 값 찾기	
		float MaxDistance = -99999.f;
		AEnemyBase* TmpEnemy = TargetEnemy;
		for (const auto& pair : MBoundEnemies)
		{
			// #1. Target Enemy 제외
			if (pair.Key == TargetEnemy) continue;

			// #2. 현 Target Enemy 거리보다 작은 거리 값 중 최대 값
			if (pair.Value < *MBoundEnemies.Find(TargetEnemy)
				&&	pair.Value > MaxDistance)
			{
				MaxDistance = pair.Value;
				TmpEnemy = pair.Key;
			}
		}

		CheckNull(TmpEnemy);
		TargetEnemy = TmpEnemy;
	}

}

 

Details

 

  1. 위와 동일합니다.

 

3. FocusOnTarget()

/*	****************************************************************************
*	목적:
*		Target Lock이 켜져 있을 때, Target Enemy로 선정된  Actor를 바라보도록 합니다.
*	설명:
*		1. Player Location과 Enemy Location을 활용하여 LookAtRotation 값을 구합니다.
*		2. Controller Rotation을 위에서 구한 회전 값으로 설정합니다.
* 
*	****************************************************************************/

void APlayerCharacter::FocusOnTarget()
{
	CheckFalse(TargetingLockOn);
	CheckNull(TargetEnemy);

	// #1. FindLookAtRotation
	APlayerCameraManager* camManager = GetWorld()->GetFirstPlayerController()->PlayerCameraManager;
	FVector Start = camManager->GetCameraLocation();
	FVector Target = TargetEnemy->GetActorLocation();

	FRotator Rotation = UKismetMathLibrary::FindLookAtRotation(Start, Target);
	GetController()->SetControlRotation(FRotator(0.f, Rotation.Yaw, 0.f));

}

 

Details

 

  • 최종적으로, Target Enemy로 선정된 적 객체를 바라보도록, Player의 Rotation 값을 세팅해줍니다. 

 

결과 화면

 

 

 

'개인프로젝트' 카테고리의 다른 글

[Unreal_C++_DarkSoul]#8_문제 해결, Send Damage 방식 수정  (0) 2022.12.18
[Unreal_C++_DarkSoul]#7_문제 해결, Magic Projectile  (0) 2022.12.17
[Unreal_C++_DarkSoul]#5_기능 구현, Target Point, Enemy Spawn 위치  (0) 2022.12.10
[Unreal_C++_DarkSoul]#4_문제 해결, Data Table 로드 함수  (0) 2022.11.27
[Unreal_C++_DarkSoul]#3_기능 구현, Custom Structure, Custom Enumeration  (0) 2022.11.23
  1.  
  2. [Unreal_C++_DarkSoul]#6_Targeting 기능
'개인프로젝트' 카테고리의 다른 글
  • [Unreal_C++_DarkSoul]#8_문제 해결, Send Damage 방식 수정
  • [Unreal_C++_DarkSoul]#7_문제 해결, Magic Projectile
  • [Unreal_C++_DarkSoul]#5_기능 구현, Target Point, Enemy Spawn 위치
  • [Unreal_C++_DarkSoul]#4_문제 해결, Data Table 로드 함수
Hardii2
Hardii2
개발 블로그Hardii2 님의 블로그입니다.
Hardii2
개발 블로그
Hardii2
전체
오늘
어제
  • 분류 전체보기
    • 알고리즘
    • 웹 개발
      • Node.js
      • React
    • 게임개발
      • DirectX12
      • 관련 지식
      • Unreal C++
      • Unreal 블루프린트
    • 언어
      • Effective C++
      • Basic C++
      • 디자인 패턴
      • 자료구조
      • 기술 질문
    • 문제 풀이
      • BOJ 문제 풀이
      • Programmers 문제 풀이
      • geeksForgeeks 문제 풀이
    • 수학
      • 확률과 통계
      • 게임수학
    • 개인프로젝트
    • 그룹프로젝트
      • PM
      • Dev
    • Github

블로그 메뉴

  • 홈
  • 글쓰기

공지사항

인기 글

태그

  • stl
  • dfs
  • C++
  • 그래프
  • 우선순위 큐
  • DP
  • unreal
  • 디자인 패턴
  • 최단 경로
  • BFS
  • programmers
  • set
  • 정렬
  • 트리
  • Unreal Blueprint
  • 개발
  • BOJ
  • 기술 질문
  • Effective C++
  • 알고리즘

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
Hardii2
[Unreal_C++_DarkSoul]#6_기능 구현, Targeting 기능
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.