본문으로 건너뛰기
게임 수학 · 게임 AI 기초집LESSON 11

투사체 기초

난이도초급
예상 시간45분
선수지식4강의 방향 벡터, 8강의 회전

11강. 투사체 기초

1. 이번 강의에서 해결할 문제

투사체가 목표와 다른 방향으로 날아가거나 위치 차이를 그대로 속도로 사용해 거리에 따라 속도가 바뀝니다. 방향과 속력을 분리하고 예상 도달 시간을 계산합니다.

2. 학습 목표

3. 핵심 개념

Direction은 길이 1인 방향, Speed는 cm/s, Velocity는 방향과 속력을 함께 가진 cm/s 벡터입니다.

Velocity = normalize(Target - Muzzle) × Speed

Time = Distance / Speed

Time은 목표가 움직이지 않고 중력·가속이 없는 단순 모델입니다. 움직이는 목표 예측과 탄도는 후속 수학·AI 심화 주제입니다.

4. 단계별 실습

C++ · 파일 경로: Source/TopDownSurvival/Combat/CombatProjectile.h

CombatProjectile.h
#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CombatProjectile.generated.h"

class UProjectileMovementComponent;
class USphereComponent;

UCLASS()
class TOPDOWNSURVIVAL_API ACombatProjectile : public AActor
{
GENERATED_BODY()

public:
ACombatProjectile();

protected:
UPROPERTY(VisibleAnywhere, Category = "Projectile")
TObjectPtr<USphereComponent> CollisionSphere;

UPROPERTY(VisibleAnywhere, Category = "Projectile")
TObjectPtr<UProjectileMovementComponent> Movement;
};

C++ · 파일 경로: Source/TopDownSurvival/Combat/CombatProjectile.cpp

CombatProjectile.cpp
#include "Combat/CombatProjectile.h"

#include "Components/SphereComponent.h"
#include "GameFramework/ProjectileMovementComponent.h"

ACombatProjectile::ACombatProjectile()
{
PrimaryActorTick.bCanEverTick = false;

CollisionSphere = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionSphere"));
CollisionSphere->InitSphereRadius(12.0f);
CollisionSphere->SetCollisionProfileName(TEXT("Projectile"));
SetRootComponent(CollisionSphere);

Movement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Movement"));
Movement->InitialSpeed = 900.0f;
Movement->MaxSpeed = 900.0f;
Movement->ProjectileGravityScale = 0.0f;
Movement->bRotationFollowsVelocity = true;

InitialLifeSpan = 5.0f;
}

적 발사 함수

MathAIEnemyCharacter.cpp · FireProjectile
void AMathAIEnemyCharacter::FireProjectile(AActor* Target)
{
if (!ProjectileClass || !IsValid(Target)) return;

const FVector Muzzle = GetActorLocation() + GetActorForwardVector() * 80.0f;
const FVector Direction =
(Target->GetActorLocation() - Muzzle).GetSafeNormal();
if (Direction.IsNearlyZero()) return;

FActorSpawnParameters Params;
Params.Owner = this;
Params.Instigator = this;
Params.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;

GetWorld()->SpawnActor<ACombatProjectile>(
ProjectileClass, Muzzle, Direction.Rotation(), Params);
}

Blueprint 작업

BP_CombatProjectile 자식을 만들고 Sphere에 작은 기본 Mesh를 붙입니다. Collision Preset의 Projectile이 없다면 프로젝트 전용 Object Channel을 만들거나 적절한 Custom 설정을 사용합니다.

5. 코드와 수학·AI가 동작하는 이유

정규화로 거리를 제거해 모든 발사체가 같은 InitialSpeed를 사용합니다. Direction.Rotation은 로컬 Forward를 발사 방향으로 돌립니다. ProjectileMovementComponent가 이동과 충돌 Sweep을 처리하므로 사용자 Tick이 필요 없습니다.

6. 자주 하는 실수와 해결법

7. 직접 실습

8. 이해 점검 질문 3개

9. 핵심 요약

MINI QUIZ

투사체 기초 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“투사체 기초”에서 다음 단계로 넘어가기 전에 확인할 핵심은 무엇인가요?
  2. 문제 2“투사체 기초”에서 ‘Target - Muzzle을 정규화하지 않음’ 문제가 생겼습니다. 가장 알맞은 진단 또는 대응은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

11강. 투사체 기초 미완료 상태