Unreal - ProjectTile을 사용한 원거리 AI 만들기

2025. 5. 9. 06:48·Unreal5 프로젝트 다이어리

근거리 AI를 기반으로 원거리공격을하는 AI를 만들어보겠습니다

근거리공격 AI의 객체부터 만들어주겠습니다

BasicSkeleton을 기반으로 블루프린트를 복사해 추가해주고 무기를 들려주었습니다

사용할 슈팅 애니메이션을 Mixamo에서 가져온뒤 리타게팅해주겠습니다

공격하는 BehaviorTree에서 Service노드를 조건을 바꿔주겠습니다

원래의 코드입니다

기본코드는 170의 거리기준으로 공격을 하기떄문에 이 170값을

변수로 선언하고 property값으로 변동할수있도록 해주겠습니다

 

변수로 선언하며 Property로 수정 가능하게 추가

 

조건을 attackDistance값으로 변동하였습니다

 

원래있던 BT를 복사후 원거리 AI에게만 적용될 BT의 Attack Distance값을 170에서 700으로 바꿔주었습니다

 

또한 AI의 Controller 블루프린트도 복사해서 바꾼 BT를 할당시켜주었습니다

Perception의 인지범위를 넓게 설정해주었습니다

 

원거리AI가 사용하는 AI Controller를 변동해주었습니다

또한 이 에셋의 메테리얼도 Dissolve를 사용할수있게 Node를 추가해주었습니다

하는법은 이전글에 작성해두었으니 궁금하신분은 참고하시길바랍니다

 

2025.05.08 - [Unreal5 프로젝트 다이어리] - Unreal - Dissolve Material

 

Unreal - Dissolve Material

Behavior Tree의 AI가 죽었을때 애니메이션이 나오면서 사라지게하는것도 나쁘지않지만갑자기 사라져버리는것보다는 점점 사라지면서 마지막에는 없어지는방식으로 표현한다면 조금더 자연스러

lucodev.tistory.com

 

그리고 공격 애니메이션을 슈팅 애니메이션으로 바꿔주었습니다

 

결과물

 

 

그럼 크로스보우로 원거리 공격할때 투사체를 추가해주겠습니다

투사체가 나가는 위치는 크로스보우의 입구에서

투사체나가는 함수의 호출은 원거리공격 애니메이션 노티파이에서 불러오겠습니다

 

보통 원거리공격은 두가지의 피격판정을 가집니다

한개는 ProjectTile과 HitScan입니다

HitScan이란 에임안에 적이 들어와있으면 무조건 맞는 방식

ProjectTile이란 물리법칙을 가지고있는 투사체가 발사되는 방식입니다

 

예를들면 오버워치의 리퍼의 공격방식을 HitScan이라고합니다

 

솔져같은 경우 프로젝트타일의 총알방식을 사용한 예시입니다

 

 

투사체는 ProjectTile로 생성하겠습니다

.h입니다

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

	UPROPERTY(EditAnywhere, Category = "MySettings")
	USceneComponent* sceneComp;

	UPROPERTY(EditAnywhere, Category="MySettings")
	UCapsuleComponent* collisionComp;

	UPROPERTY(EditAnywhere, Category = "MySettings")
	USkeletalMeshComponent* projectTileComp;

	UPROPERTY(EditAnywhere, Category = "MySettings")
	UProjectileMovementComponent* projectileMovement;

	class ASwordCharacter* swordPlayer;
};

 

.cpp입니다

ABowSkeletonProjectTile::ABowSkeletonProjectTile()
{
	PrimaryActorTick.bCanEverTick = true;
	//Scene
	sceneComp = CreateDefaultSubobject<USceneComponent>(TEXT("sceneComp"));
	RootComponent = sceneComp;
	//Collision
	collisionComp = CreateDefaultSubobject<UCapsuleComponent>(TEXT("SphereComponent"));
	collisionComp->SetCollisionProfileName(TEXT("BlockAll"));
	collisionComp->SetupAttachment(RootComponent);
	//SkeletalMeshComp
	projectTileComp = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("arrowMesh"));
	projectTileComp->SetupAttachment(RootComponent);
	projectTileComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
	//ProjectTile
	projectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("projectTileMevement"));
	projectileMovement->InitialSpeed = 2500.f;
	projectileMovement->MaxSpeed = 2500.f;
	projectileMovement->bRotationFollowsVelocity = true;
	projectileMovement->ProjectileGravityScale = 0.3f; 
}

void ABowSkeletonProjectTile::BeginPlay()
{
	Super::BeginPlay();
	collisionComp->OnComponentBeginOverlap.AddDynamic(this, &ABowSkeletonProjectTile::OnBeginOverlap);
}

void ABowSkeletonProjectTile::OnBeginOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
	FString hitActorName = OtherActor->GetName();
	if (hitActorName.Contains(TEXT("SwordCharacter")))
	{
		swordPlayer = Cast<ASwordCharacter>(OtherActor);
		swordPlayer->playerCurrentHp -= 500;
		Destroy();
	}
}

화살을 할당해주어 ProjectTile을 설정하였습니다

이 projecttile은 0.3의 중력을 가지고있으며 2500의 속도로 움직입니다

만약 플레이어와 오버랩될시 Destroy됩니다

오버랩될시의 추후의 작업은 마지막에서 하겠습니다

 

잘 이동하는것을 확인할수있습니다

오버랩 이벤트도 문제없이 되는것을 확인할수있습니다

발사 위치를 지정해주겠습니다

발사 위치는 WeaponSocket에서 발사되겠습니다

 

그럼 스폰함수를 만들겠습니다

사용할 함수 그리고 제가만든 ABowSkeletonProjectTile을 참조할 arrowProjectTile변수를 선언

UFUNCTION()
void SpawnArrow();

UPROPERTY(EditAnywhere, Category="MySettings")
TSubclassOf<ABowSkeletonProjectTile> arrowProjectTile;

 

프로퍼티로 블루프린트를 할당해줍니다

 

이미 모션워핑으로플레이어의 위치를 찾을수있으니 FindWarpTarget으로 위치를 불러온다음

WeaponSocket에서 target의 위치방향으로 스폰하면되겠습니다

타겟에서 스폰위치를 빼면 방향이 나옵니다

void ABasicSkeletonEnemy::SpawnArrow()
{
	FVector spawnLoc = GetMesh()->GetSocketLocation(TEXT("WeaponSocket"));
	if (motionWarpComponent)
	{
		const FMotionWarpingTarget* target = motionWarpComponent->FindWarpTarget(TEXT("PlayerTarget"));
		if (target)
		{
			FVector targetLoc = target->GetLocation();
			FVector direction = targetLoc - spawnLoc;
			FRotator spawnRot = direction.Rotation();

			FActorSpawnParameters spawnParams;
			spawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
			ABowSkeletonProjectTile* SpawnedArrow = GetWorld()->SpawnActor<ABowSkeletonProjectTile>(arrowProjectTile,spawnLoc,spawnRot,spawnParams);
			if (SpawnedArrow)
			{
				SpawnedArrow->SetLifeSpan(5.0f);  
			}
		}
	}
}

 

AI의 애님인스턴스에서 해당 함수를 호출할 노티파이를 만들어줍니다

void USkeletonEnemyAnimInstance::AnimNotify_SpawnArrow()
{
	skeletonEnemy->SpawnArrow();
}

 

노티파이를 찍어주면

 

최종결과물

 

 

 

 

'Unreal5 프로젝트 다이어리' 카테고리의 다른 글

Uneal - EQS Strafe이동  (0) 2025.05.10
Unreal - AI에게 HP 프로그래스바 붙히기  (0) 2025.05.09
Unreal - Behavior Tree(5) 스폰 / 디스폰  (0) 2025.05.08
Unreal - Dissolve Material  (0) 2025.05.08
Unreal - Behavior Tree(4) AI Perception Team ID  (1) 2025.05.04
'Unreal5 프로젝트 다이어리' 카테고리의 다른 글
  • Uneal - EQS Strafe이동
  • Unreal - AI에게 HP 프로그래스바 붙히기
  • Unreal - Behavior Tree(5) 스폰 / 디스폰
  • Unreal - Dissolve Material
lucodev
lucodev
커피와 노트북 그리고 개발
  • lucodev
    루코 개발테이블
    lucodev
  • 전체
    오늘
    어제
    • 분류 전체보기 (130) N
      • Unreal5 프로젝트 다이어리 (73)
      • Unreal5 프로젝트 다이어리2 (9) N
      • Unreal 팁 (8)
      • Unreal 디버깅 (8)
      • C++ 프로그래머스 다이어리 (24)
        • Stack (3)
        • Hash (4)
        • Heap (2)
        • Sort (4)
        • Exhaustive search (0)
      • 코드 개인보관함 (8)
  • 인기 글

  • 최근 글

  • 최근 댓글

  • 링크

  • 공지사항

  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 태그

    언리얼 비헤이비어트리
    언리얼 페이드 아웃
    언리얼 foot step
    unreal loading
    언리얼 behavior tree
    언리얼 시퀀스
    언리얼 behaviortree
    unreal 로딩
    언리얼 look at
    unreal look at
    언리얼 로딩
    unreal 시퀀스
    unreal 컷씬
    언리얼
    언리얼 모션매칭
    언리얼 컷씬
    언리얼 motionmatching
    unreal sequence
    unreal 모션매칭
    언리얼 로딩창
  • hELLO· Designed By정상우.v4.10.3
lucodev
Unreal - ProjectTile을 사용한 원거리 AI 만들기
상단으로

티스토리툴바