Unreal - 공격 ( 타겟, 논타겟)

Overcle·2023년 2월 27일
0

Unreal Study

목록 보기
1/5

언리얼을 넘어서 게임에 공격 방식에는 크게 2가지의 방식으로 나뉘어 진다.

  • 타겟팅
  • 논타겟팅

이름 그말대로 범위 안에 있으면 무조건 데미지를 넣는 타겟팅.

범위 안에 있으며, 속도, 시간, 등등을 고려해 조건에 맞아야만 데미지를 넣는 논타겟.

GPT 답변

비디오 게임의 맥락에서 타겟팅은 게임 세계에서 특정 개체나 캐릭터를 선택하거나 집중하는 행위를 의미합니다. 
여기에는 게임 자체에 의한 자동 선택(예: 특정 범위 내의 적들이 자동으로 무기의 표적이 됨) 또는 입력 컨트롤을 사용하여 
플레이어가 수동으로 선택하는 것(예: 플레이어가 마우스를 사용하여 특정 적을 클릭하는 것이 포함될 수 있습니다. 그들을 목표로).


반면 논타겟팅 게임플레이는 일반적으로 플레이어의 행동이 특정 개체나 캐릭터를 명시적으로 타겟팅할 필요가 없는 게임을 말합니다. 
여기에는 특정 반경 내의 모든 적에게 피해를 주는 영역 효과 주문과 같이 동작이 더 추상적이고 영역 기반인 게임 또는 플레이어가 자신의 동작을 덜 세밀하게 제어할 수 있는 게임이 포함될 수 있습니다. 
플레이어 캐릭터가 명시적으로 타겟팅할 필요 없이 주변의 적을 자동으로 공격하는 액션 게임입니다.


타겟팅과 비타겟팅 게임플레이 사이의 선택은 종종 개발 중인 게임 유형과 원하는 플레이어 경험에 따라 달라집니다. 
예를 들어, 1인칭 슈팅 게임이나 격투 게임과 같은 액션 지향적인 게임은 플레이어가 자신의 행동을 정확하게 제어할 수 있도록 타겟팅 메커니즘에 크게 의존하는 반면, 
더 많은 전략 또는 전술 게임은 플레이어를 격려하기 위해 영역 기반 또는 추상 메커니즘에 더 집중할 수 있습니다.
전략적으로 생각하고 주변 환경을 활용합니다.

타겟팅 공격방식


알고리즘은 간단하다. 적이 공격범위 안에 들어오면, 확정적으로 이벤트를 실행하면된다.

우선 해당 코드에선, 몬스터에는 AI Constroller, BehaviorTree 방식을 사용했다.

  1. Monster의 컨트롤러 불러오기
	AAIController* MonsterController = Cast<AAIController>(GetController());
  1. Target정보 가져오기 //플레이어 정보
	ACharacter* Target = Cast<ACharacter>(MonsterController->GetBlackboardComponent()->GetValueAsObject(TEXT("Target")));
  1. 공격 이벤트 구현.
void AMinionWarrior::Attack()
{
if (IsValid(Target))
	{
    	//ActorSPawn 설정값 설정.
		FActorSpawnParameters	SpawnParam;
		SpawnParam.Template = mHitActor;
		SpawnParam.SpawnCollisionHandlingOverride =
			ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

		// 자신과 타겟 방향값 설정.
		FVector	Dir = GetActorLocation() - Target->GetActorLocation();
		Dir.Normalize();

		// 피격위치 설정.
		FVector	ParticleLoc = Target->GetActorLocation() + Dir * 50.f;

		// 피격위치에, 자신과 타겟 방향으로, 피격이펙트를 설정한 옵션으로 Particle을 생성한다.
		AParticCascade* Particle =
			GetWorld()->SpawnActor<AParticCascade>(
				ParticleLoc,
				Dir.Rotation(),
				SpawnParam);

		// 타겟의 데미지 이벤트를 선언하며, 자신의 몬스터 데미지와 자신이 누군지를 넘겨준다.
		Target->TakeDamage((float)mInfo.AttackPoint, FDamageEvent(), GetController(), this);
	}
}

위의 코드로 타겟팅 공격 방식을 구현 할 수 있다.
앞서 mHitActor Patricle 구현도 필요하다. 혹시 모르니 해당 코드도 넣어둔다

생성자에서 진행함.

	mHitActor = CreateDefaultSubobject<AParticCascade>(TEXT("HitParticle"));

	AParticCascade* Particle = Cast<AParticCascade>(mHitActor);
	Particle->SetParticle(TEXT("ParticleSystem'/Game/ParagonYin/FX/Particles/Yin/Abilities/Primary/FX/P_Yin_Primary_Impact.P_Yin_Primary_Impact'"));
	Particle->SetSound(TEXT("SoundWave'/Game/Sound/Fire1.Fire1'"));

논타겟팅 공격방식


해당 수업에서는 총을 기준으로 구현을 함.

  1. HitActor, MuzzlePatricle 생성.
[생성자에서]

	mHitActor = CreateDefaultSubobject<AParticCascade>(TEXT("HitParticle"));

	mMuzzleParticle = CreateDefaultSubobject<AParticCascade>(TEXT("MuzzleParticle"));

	//플레이어를 피격시 해당지점에 생길 Patricle 생성.
	AParticCascade* Particle = Cast<AParticCascade>(mHitActor);
	Particle->SetParticle(TEXT("ParticleSystem'/Game/ParagonMinions/FX/Particles/Minions/Shared/P_MinionMuzzle.P_MinionMuzzle'"));
	Particle->SetSound(TEXT("SoundWave'/Game/Sound/Fire1.Fire1'"));
  1. BehaviorTree 알고리즘으로 인해. 플레이어 탐색 > 발견 > 거리 충족 및 공격 이벤트 발생이 된다면. 공격 알고리즘 Attack 실행.
void AMinionRanger::Attack()
{
	//공격시 Particle이 생길 지점을 지정.
	FVector MuzzleLoc = GetMesh()->GetSocketLocation(TEXT("Muzzle_Front_XForward"));


	// Parameter 설정.
	FActorSpawnParameters	SpawnParam;
	SpawnParam.SpawnCollisionHandlingOverride =	ESpawnActorCollisionHandlingMethod::AlwaysSpawn;

	// 파티클 발사체를 앞서 지정한 위치, 몬스터 잔방 방향, 설정한 파라미터 설정 으로 생성. (총열 임펙트)
	AParticCascade* MuzzleParticle = GetWorld()->SpawnActor<AParticCascade>(MuzzleLoc, GetActorForwardVector().Rotation(), SpawnParam);

	//선언한 발사체 Patricle과 Sound 설정.
	MuzzleParticle->SetParticle(TEXT("ParticleSystem'/Game/ParagonMinions/FX/Particles/Minions/Shared/P_MinionMuzzle.P_MinionMuzzle'"));
	MuzzleParticle->SetSound(TEXT("SoundWave'/Game/Sound/Fire1.Fire1'"));

	//해당 발사체가 갈 수 있는 거리를 지정. 
	FVector End = MuzzleLoc + GetActorForwardVector() * mInfo.AttackDistance;

	//제외시킬 콜리젼 지정.
	FCollisionQueryParams param(NAME_None, false, this);

	//Hit Result 변수 선언, 
	FHitResult result;

	//Single Trace 이기에 충돌한 첫번째만 저장하며, 총위치에서 몬스터 사거리 이내로 Trace를 발사해, 맞은게 있다면 True;
	bool Hit = GetWorld()->LineTraceSingleByChannel(result, MuzzleLoc, End, ECollisionChannel::ECC_GameTraceChannel7,param);


	//직관적으로 표현하기 위해 Draw Debut로 에디터에서도 보이도록 설정.
#if ENABLE_DRAW_DEBUG 

	//맞은게 있다면 Red, 없다면 Green
	FColor	Color = Hit ? FColor::Red : FColor::Green;

	//총위치에서 사거리까지 해당 색상으로 월드의 정보를 담고있는 Object, 시작점, 끝점, 색상, 유지시간, 라인 두깨를 의미한다.
	//bPersistentLine은 선이 지워지는지에 대한 유무 이며, 디버깅 할 때 유용하다.
	DrawDebugLine(GetWorld(), MuzzleLoc, End, Color,
		false, 1.f, 2.f);

#endif
	if (Hit)
	{
		//Spawn Paramter 설정.
		FActorSpawnParameters	HitSpawnParam;
		//HitSpawnParam.Template = mHitActor;
		HitSpawnParam.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;


		//Hit, 맞았다면. 맞은 위치에 Particle SPawn.
		AParticCascade* Particle =
			GetWorld()->SpawnActor<AParticCascade>(
				result.ImpactPoint,
				result.ImpactNormal.Rotation(),
				HitSpawnParam);

		//생성된 Particle 정보 설정.
		Particle->SetParticle(TEXT("ParticleSystem'/Game/ParagonYin/FX/Particles/Yin/Abilities/Primary/FX/P_Yin_Primary_Impact.P_Yin_Primary_Impact'"));
		Particle->SetSound(TEXT("SoundWave'/Game/Sound/Fire1.Fire1'"));


		//맞은 Actor에게 데미지 전달.
		result.GetActor()->TakeDamage(
			(float)mInfo.AttackPoint,
			FDamageEvent(), GetController(), this);
	}

	
}
profile
게임 프로그래머 지망생의 발자취

0개의 댓글