언리얼 공부/C++

총알만들기

jeongchanhyo 2025. 2. 27. 20:58

총알구조

총알도 3종류로 만들것이다. 일반탄, 적은 뚫고 지나가는 관통탄, 무언가에 닿으면 폭발하는 로켓

그 3 종류의 총알이 모두 필요한것을 일단 만들것이다.

  • 총알 생성
  • 총알 날라가기
  • 총알 적중

부모클래스 헤더파일 만들기

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SphereComponent.h"
#include "BulletBase.generated.h"

UCLASS()
class SHADOW_OF_THE_DESERT_API ABulletBase : public AActor
{
	GENERATED_BODY()
	
public:	
	ABulletBase();

protected:
	virtual void BeginPlay() override;

public:	
	virtual void Tick(float DeltaTime) override;

	void Initialize(FVector Direction, float Damage, APawn* InstigatorPawn);

	UFUNCTION(BlueprintCallable, Category = "Weapon")
	virtual void OnHit(
		UPrimitiveComponent* OverlappedComponent,
		AActor* OtherActor,
		UPrimitiveComponent* OtherComp,
		int32 OtherBodyIndex,
		bool bFromSweep,
		const FHitResult& SweepResult
	);
	
	virtual void BulletEffects();

protected:
	UPROPERTY(VisibleAnywhere)
	UStaticMeshComponent* BulletMesh;

	UPROPERTY(VisibleAnywhere)
	USphereComponent* HitCollision;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bullet|Effects")
	USoundBase* HitSound;

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bullet|Effects")
	UParticleSystem* HitParticle;

	UPROPERTY(VisibleAnywhere)
	float Speed;

	FVector MovementDirection;
	float BulletDamage;
};

매개변수

  • BulletMesh - 총알 외관
  • HitCollision - 때리는 범위
  • HitSound - 때렸을 때 소리
  • HitParticle - 때렸을 때 이펙트
  • Speed - 총알 속도
  • BulletDamage - 총알 데미지

함수

  • ABulletBase() - 생성자
  • BeginPlay() - 게임 시작 시 호출
  • Tick - 매 틱(프레임)마다 호출되는 함수(총알이 이동할 때 사용)
  • Initialize - 초기화(총알이 날라갈 방향, 데미지, 발사한 사람을 가져가서 발사)
  • OnHit - 적중 시 발동, 데미지를 줌
  • BulletEffects() - 총알 사운드, 파티클 등이 발동되는 함수

구현

생성자

ABulletBase::ABulletBase()
{
	PrimaryActorTick.bCanEverTick = true;

	BulletMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("BulletMesh"));
	RootComponent = BulletMesh;

	USceneComponent* Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
	RootComponent = Root;
	BulletMesh->SetupAttachment(Root);

	// 콜리전 설정
	HitCollision = CreateDefaultSubobject<USphereComponent>(TEXT("HitCollision"));
	HitCollision->SetCollisionProfileName(TEXT("OverlapAllDynamic"));
	HitCollision->SetupAttachment(BulletMesh);
	HitCollision->OnComponentBeginOverlap.AddDynamic(this, &ABulletBase::OnHit);

	Speed = 3000.0f;
	BulletDamage = 0.0f;
}

Tick함수를 켜주고 총알 메쉬와 콜리전 설정을 해준다.

	HitCollision->OnComponentBeginOverlap.AddDynamic(this, &ABulletBase::OnHit);

여기가 중요한데 이 콜리전이 Overlap 즉, 겹치면 이 객체의 OnHit함수를 불러오겠다 라는 뜻이다.

그 외에는 총알의 속도와 데미지를 초기화해준다.

Tick함수

void ABulletBase::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FVector NewLocation = GetActorLocation() + MovementDirection * Speed * DeltaTime;
	SetActorLocation(NewLocation);

}

이 함수는 매 프레임마다 적용되는 함수로서 총알이 매 프레임마다 설정해준 속도만큼 이동한다는 함수다.

초기화함수

void ABulletBase::Initialize(FVector Direction, float Damage, APawn* InstigatorPawn)
{
	MovementDirection = Direction;
	BulletDamage = Damage;
	SetInstigator(InstigatorPawn);

	// 매시 방향 설정
	if (!MovementDirection.IsNearlyZero())
	{
		const FRotator NewRotation = FRotationMatrix::MakeFromX(MovementDirection).Rotator();
		SetActorRotation(NewRotation);
	}

}

총알이 생성될 때 값을 받아서 총알이 나아갈 방향과 데미지를 설정해준다.

충돌함수

void ABulletBase::OnHit(
	UPrimitiveComponent* OverlappedComponent,
	AActor* OtherActor,
	UPrimitiveComponent* OtherComp,
	int32 OtherBodyIndex,
	bool bFromSweep,
	const FHitResult& SweepResult
)
{
}

충돌 시 발동될 함수다. 불러올것으로는 위에서부터

  • 충돌이 발생한 총알
  • 충돌이 발생한 다른 액터
  • 다른 액터의 컴포넌트인데 물리적 속성을 가지고있다.(자세히는 모름)
  • 충돌이 발생한 다른 액터의 복수의 액터 중 어디랑 충돌했는지 부위를 나타낸다. 주로 복잡한 형태의 액터에 사용됨
  • 이 값은 충돌이 스위프(sweep) 방식으로 발생했는지를 나타내는 불리언 값. 스위프는 물체가 이동하는 경로를 따라 충돌을 감지하는 방식으로, 이 값이 true일 경우 스위프 방식으로 충돌이 발생했다는 의미다.
  • 충돌 결과에 대한 정보를 담고 있는 구조체다.충돌 지점, 위치, 백터 등 여러가지 정보를 포함한다.

자세한 내용은 안에서 구현

이펙트

void ABulletBase::BulletEffects()
{
	UParticleSystemComponent* Particle = nullptr;

	if (HitParticle)
	{
		Particle = UGameplayStatics::SpawnEmitterAtLocation(
			GetWorld(),
			HitParticle,
			GetActorLocation(),
			GetActorRotation(),
			false
		);
	}
	if (HitSound)
	{
		UAudioComponent* AudioComponent = UGameplayStatics::SpawnSoundAtLocation(
			GetWorld(),
			HitSound,
			GetActorLocation()
		);
	}
}

파티클과 사운드가 들어가 소환되는 파티클이다.

 

이런식으로 골자를 만들어 놨으면 끝!. 이제는 총알의 OnHit만 구현해주면 된다.

'언리얼 공부 > C++' 카테고리의 다른 글

일반탄환, 관통탄, 폭발탄  (0) 2025.03.04
총 만들기  (0) 2025.02.25
순수가상함수, 추상클래스 그리고 인스턴스  (0) 2025.02.20
플로우 차트  (0) 2025.02.18
FPS무기 구조 생각  (0) 2025.02.17