[Unreal Engine 5] Obstacle Assault 03

๊ฐฌ๋ฏธยท2025๋…„ 4์›” 6์ผ

[Unreal Engine 5] Obstacle Assault

๋ชฉ๋ก ๋ณด๊ธฐ
3/5
post-thumbnail

โฐTick

๐ŸŽฎGame Loop

  1. ๊ฒŒ์ž„ ์—”์ง„์ด ํ”Œ๋ ˆ์ด์–ด์˜ ์ธํ’‹์„ ๊ฐ€์ ธ์˜ด
  2. ์ธํ’‹ ์ •๋ณด๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฒŒ์ž„ ์ƒํƒœ ์—…๋ฐ์ดํŠธ
  3. ๊ฒŒ์ž„ ์—”์ง„์—์„œ ๊ฒŒ์ž„ ์ƒํƒœ๋ฅผ ๊ฐ€์ ธ์™€ ํ”Œ๋ ˆ์ด์–ด, ์นด๋ฉ”๋ผ ๋“ฑ์˜ ์œ„์น˜๋ฅผ ์ •ํ•œ ๋‹ค์Œ ํ™”๋ฉด์— ๋ Œ๋”๋ง / ์ผ๋ จ์˜ ์ˆซ์ž๋“ค์ด ํ™”๋ฉด์— ํ‘œ์‹œ๋  ์ด๋ฏธ์ง€๋กœ ๋ฐ”๋€œ

๐Ÿ“š์šฉ์–ด ์ •๋ฆฌ

  • ํ”„๋ ˆ์ž„
    : ๋™์˜์ƒ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ทธ๋ฆผ ์ค‘ ํ•˜๋‚˜
  • ํ”„๋ ˆ์ž„๋ฅ  (FPS)
    : ์ปดํ“จํ„ฐ๊ฐ€ 1์ดˆ๋‹น ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒŒ์ž„ ๋ฃจํ”„์˜ ์ˆ˜๊ณ 
  • ์ดˆ๋‹น ํ”„๋ ˆ์ž„ ์ˆ˜
    : ์ธํ’‹์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜์—ฌ ๋ Œ๋”๋งํ•˜๋Š” ๋นˆ๋„
    โ†’ ์–ธ๋ฆฌ์–ผ์—์„œ๋Š” Tick ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ๊ฒŒ์ž„ ๋ฃจํ”„์˜ ์ค‘๊ฐ„ ๋‹จ๊ณ„๋ฅผ ์ง„ํ–‰ํ•จ
  • Tick
    : ๋ชจ๋“  ํ”„๋ ˆ์ž„ ํ˜ธ์ถœ, ์ด๋ฒคํŠธ๋กœ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ์—๋„ ์กด์žฌํ•˜๋Š” ํ•จ์ˆ˜

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

  • ํ”Œ๋žซํผ ์ด๋™์‹œํ‚ค๋Š” ์ž‘์—…,
    ํ”Œ๋žซํผ์˜ ํฌ๊ธฐ๋ฅผ ๋‚ฉ์ž‘ํ•œ ์ง์œก๋ฉด์ฒด ๋ชจ์–‘์œผ๋กœ ๋ฐ”๊พธ๊ณ  ํ•จ์ˆ˜์— ๊ธฐ๋Šฅ ์ถ”๊ฐ€
void AMovingPlatform::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	MyVector.Y = MyVector.Y + 1;

	SetActorLocation(MyVector);

}

๐Ÿšฒ์ง€์—ญ ๋ณ€์ˆ˜(Local Variables)

๐ŸŒ Scope

  • ๋ณ€์ˆ˜๊ฐ€ ์œ ์ง€๋˜๋Š” ๊ธฐ๊ฐ„ ์˜๋ฏธ
  • ์ผ๋ฐ˜์ ์œผ๋กœ C++์—์„œ ๋ณ€์ˆ˜๋Š” ๊ตฌ๋ฌธ์˜ ์ค‘๊ด„ํ˜ธ ์‚ฌ์ด์— ์žˆ์„ ๋•Œ ์œ ํšจํ•จ
void AMovingPlatform::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	FVector LocalVector = MyVector; //์ง€์—ญ ๋ณ€์ˆ˜!!

	LocalVector.Z = LocalVector.Z + 100;

	MyVector.Y = MyVector.Y + 1;

	SetActorLocation(LocalVector);

}

๐Ÿ’ฌ์˜์‚ฌ(Pseudo) ์ฝ”๋“œ

๐Ÿ“š์šฉ์–ด ์ •๋ฆฌ

  • ์˜์‚ฌ์ฝ”๋“œ
    : ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ ์‚ฌ์šฉํ•  ๋‹จ๊ณ„๋ฅผ ์ผ๋ฐ˜์ ์ธ ์–ธ์–ด๋กœ ์„ค๋ช…ํ•œ ๊ฒƒ
  • ์ฃผ์„
    : ์ปดํŒŒ์ผ๋Ÿฌ์—์„œ ๋ฌด์‹œํ•˜๋Š” ์ฝ”๋“œ

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

  • ๋‹ค์Œ์œผ๋กœ ํ•  ์ž‘์—… ์ฃผ์„์œผ๋กœ ์ž‘์„ฑํ•ด๋‘๊ธฐ
	// Move platform forwards
		// Get current location
		// Add vector to that location
		// Set the location
	// Send platform back if gone too far
		// Check how far we've moved
		// Reverse direction of motion if gone too far

๐Ÿ“คํ•จ์ˆ˜ ๋ฐ˜ํ™˜ ๊ฐ’

๐Ÿ“š์šฉ์–ด ์ •๋ฆฌ

  • ํ‘œํ˜„์‹
    : ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ ์กฐ๊ฐ
  • ๋ฌธ (Statement=์ฝ”๋“œ ์กฐ๊ฐ)
    : ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•  ๋™์ž‘

๐ŸŽ‡ํ‘œํ˜„์‹(Expressions)

  • MyVector
  • LocalVector.Z + 100
  • FVector LocalVector = MyVector;
    โ†’ ๊ฐ’ ์—†์Œ, ๊ฐ’ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Œ โ†’ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๋™์ž‘์ด ์žˆ๋‹ค๊ณ  C++์— ์•Œ๋ฆด ๋ฟ
    โ†’ ํ‘œํ˜„์‹ ์•„๋‹˜
  • GetActorLocation()

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

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

	// Move platform forwards
		// Get current location
	FVector CurrentLocation = GetActorLocation();
		// Add vector to that location
	CurrentLocation.X = CurrentLocation.X + 1;
		// Set the location
	SetActorLocation(CurrentLocation);
	...
}

๐Ÿ•์†๋„ & ๋ธํƒ€ ํƒ€์ž„

๐Ÿ’จUsing DeltaTime

  • ์–ธ๋ฆฌ์–ผ์—์„œ ๋ธํƒ€ ํƒ€์ž„์„ ์ด์šฉํ•˜๋ฉด,
    ๊ฐ ํ”„๋ ˆ์ž„์ด ์‹คํ–‰๋˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ์–ผ๋งˆ๋‚˜ ๊ฑธ๋ฆฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Œ
  • ์–ด๋–ค ๊ฐ’์„ ๋ธํƒ€ ํƒ€์ž„์œผ๋กœ ๊ณฑํ•˜๋ฉด, ๊ฒŒ์ž„ ํ”„๋ ˆ์ž„๋ฅ ์ด ๋…๋ฆฝ์ ์œผ๋กœ ๋ณ€ํ•จ
  • ์ฆ‰, ๋น ๋ฅธ ์ปดํ“จํ„ฐ์™€ ๋А๋ฆฐ ์ปดํ“จํ„ฐ์—์„œ ๊ฒŒ์ž„์ด ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ฒŒ ๋จ
	CurrentLocation = CurrentLocation + (PlatformVelocity * DeltaTime);

๐Ÿš‡๋ฒ”์œ„ ์ง€์ • ์—ฐ์‚ฐ์ž

  • ํ”Œ๋ ˆ์ด๊ฐ€ ์‹œ์ž‘๋œ ์ดํ›„ ์–ผ๋งˆ๋‚˜ ์ด๋™ํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๋ฒ•
    1) ๋‘ ๋ฒกํ„ฐ์˜ ์ฐจ์ด โ†’ ๋‘ ์œ„์น˜์˜ ๊ฑฐ๋ฆฌ๋ฅผ ์•Œ์•„๋‚ด์•ผ ํ•จ
    2) ์–ด๋””์„œ ์‹œ์ž‘ํ–ˆ๋Š”์ง€

๐Ÿ“š์šฉ์–ด ์ •๋ฆฌ

  • ๋ฒ”์œ„ ์ง€์ • ์—ฐ์‚ฐ์ž (::)
    : ๋”๋ธ” ์ฝœ๋ก  ์—ฐ์‚ฐ์ž, ์  ์—ฐ์‚ฐ์ž์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํด๋ž˜์Šค ์•ˆ์„ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
    : ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ๋‚ด๋ถ€๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ
    ex) void AMovingPlatform::Tick(float DeltaTime)
    โ†’ Tick ํ•จ์ˆ˜๋Š” MovingPlatform ํด๋ž˜์Šค์— ์†ํ•œ๋‹ค๋Š” ๊ฑด ์•Œ๊ณ  ์žˆ์ง€๋งŒ ์ด ํด๋ž˜์Šค์˜ ํŠน์ • ์ธ์Šคํ„ด์Šค์— ์†ํ•˜์ง€๋Š” ์•Š์Œ
    โ†’ MovingPlatform์˜ ๋ชจ๋“  ์ธ์Šคํ„ด์Šค๋Š” ๊ฐ™์€ Tick ํ•จ์ˆ˜ ๊ตฌํ˜„์„ ๊ณต์œ ํ•จ(ํด๋ž˜์Šค์—ฌ์„œ)
    โ†’โ†’ Tick ํ•จ์ˆ˜๊ฐ€ MovingPlatform ํด๋ž˜์Šค์— ์†ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ๋œปํ•จ

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

  • ์ฒ˜์Œ ์œ„์น˜์™€ ํ˜„์žฌ ์œ„์น˜์˜ ๊ฑฐ๋ฆฌ ์ฐจ์ด ๊ณ„์‚ฐํ•˜๋Š” ๊ธฐ๋Šฅ ์ถ”๊ฐ€ํ•˜๊ธฐ
  • ๊ฑฐ๋ฆฌ ์ฐจ์ด ๊ฐ’์„ DistanceMoved์— ์ €์žฅ
	DistanceMoved = FVector::Dist(StartLocation, CurrentLocation);

๐Ÿ›ซIf ๋ฌธ์žฅ

  • If ๋ฌธ == C++์˜ ๋ถ„๊ธฐ๋ฌธ
    โ†’ ์ด๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ”Œ๋žซํผ์ด ์•ž๋’ค๋กœ ์›€์ง์ด๊ฒŒ ๋งŒ๋“ค๊ธฐ

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

  • ํ”Œ๋žซํผ์ด ์•ž๋’ค๋กœ ์›€์ง์ด๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ
	float DistanceMoved = FVector::Dist(StartLocation, CurrentLocation);
		// Reverse direction of motion if gone too far

	if (DistanceMoved > MovedDistance)
	{
		PlatformVelocity = -PlatformVelocity;
	}
  • ๊ทธ๋Ÿฌ๋‚˜, ์‹œ์ž‘์ ์„ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์•„ ํ”Œ๋žซํผ์ด ์Œ์ˆ˜ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™, ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ฐ˜๋Œ€๋กœ ์‹œ์ž‘์ ์„ ์ง€๋‚˜ ๊ฐ™์€ ๊ฑฐ๋ฆฌ๋ฅผ ์ด๋™ํ•จ

  • ์‹œ์ž‘์ ์„ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋„ฃ์€ ์ฝ”๋“œ โ–ผ

	float DistanceMoved = FVector::Dist(StartLocation, CurrentLocation);
		// Reverse direction of motion if gone too far

	if (DistanceMoved > MovedDistance)
	{
		PlatformVelocity = -PlatformVelocity;
		StartLocation = CurrentLocation;
	}
  • ์‹œ์ž‘์ ์„ ์ง€๋‚˜์น˜์ง€ ์•Š๊ณ  ํ•ญ์ƒ ๊ฐ™์€ ํฌ๊ธฐ ๋งŒํผ ๋˜๋Œ์•„๊ฐ€์„œ ์‹œ์ž‘์ ์œผ๋กœ ๊ฐ

๐Ÿ‘ฅ๋ฉค๋ฒ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ

Back and Forth

๐Ÿ–จC++ ์ž‘์—…๐Ÿ–จ

  • ์œ„์˜ ๊ทธ๋ฆผ์œผ๋กœ ํ‘œํ˜„ํ•œ ๊ฐœ๋…์„ ํ™œ์šฉํ•˜์—ฌ ์‹œ์ž‘์ ๊ณผ ๋์ ์„ ์ง€๋‚˜์น˜์ง€ ์•Š๊ณ 
    ํ”Œ๋žซํผ์ด ์›€์ง์ด๋„๋ก ํ•ด์ฃผ๊ธฐ
	if (DistanceMoved > MovedDistance)
	{
		FVector MoveDirection = PlatformVelocity.GetSafeNormal();
		StartLocation = StartLocation + MoveDirection * MovedDistance;
		SetActorLocation(StartLocation);
		PlatformVelocity = -PlatformVelocity;
	}

๐Ÿ“ฅ๋ธ”๋ฃจํ”„๋ฆฐํŠธ์™€ ํ•˜์œ„ ํด๋ž˜์Šค

๋ธ”๋ฃจํ”„๋ฆฐํŠธ ๋ฒ ์ด์Šค ํด๋ž˜์Šค ์ƒ์„ฑ ๋ฐฉ๋ฒ•

  • MovingPlatform ์šฐํด๋ฆญ
    โ†’ 'MovingPlatform ๊ธฐ๋ฐ˜ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค ์ƒ์„ฑ' ์„ ํƒ
    โ†’ PlatformVelocity๋Š” z์ถ• 200, MovedDistance๋Š” 500์œผ๋กœ ์„ค์ •
    โ†’ ๋ชจ์–‘์€ ๋Œ๊ธฐ๋‘ฅ ๋ชจ์–‘์œผ๋กœ ํ•ด์ฃผ๊ธฐ
    โ†’โ†’ ์‹คํ–‰ํ•ด๋ณด๋ฉด ๋Œ๊ธฐ๋‘ฅ์ด ์œ„์•„๋ž˜๋กœ ์›€์ง์ด๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ

๐Ÿฑโ€๐Ÿ‰์บ๋ฆญํ„ฐ ์ถฉ๋Œ ๊ฐ•์ œ ์ ์šฉ

  • 'MovingPlatform ๊ธฐ๋ฐ˜ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ ํด๋ž˜์Šค ์ƒ์„ฑ' โ†’ BP_PushingCube ์ƒ์„ฑ
    ์ƒ์„ฑํ•œ BP_PushingCube๋ฅผ ๋ทฐํฌํŠธ์— ์ถ”๊ฐ€ํ•ด์„œ ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ๋ธŒ ์˜†์— ๋†”๋‘๋ฉด ์–ด์ƒ‰ํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์Œ
  • ํ”Œ๋ ˆ์ด์–ด์˜ ๋ธ”๋ฃจํ”„๋ฆฐํŠธ์— MoveUpdateComponent ์ถ”๊ฐ€ํ•˜์—ฌ ์ถฉ๋Œ ๊ฐ•์ œ ์ ์šฉํ•˜๊ธฐ
  • ์ˆ˜์ • ๊ฒฐ๊ณผ โ–ผ

0๊ฐœ์˜ ๋Œ“๊ธ€