1. ํน์ ์์น์ ์์ฑํ๊ธฐ
์คํฐ ํฌ์ธํธ๊ฐ ๋ ๋ธ๋ฃจํ๋ฆฐํธ ํด๋์ค ์กํฐ๋ฅผ ์์ฑํ๊ณ ๋ ๋ฒจ ๋ด ๋ฐฐ์นํ๋ค. ์ด๋ ๊ฒ ๋ฐฐ์น๋ ์คํฐ ํฌ์ธํธ ์ค ๋๋คํ ์คํฐ ํฌ์ธํธ์ ์์น์ ์กํฐ๊ฐ ์์ฑ๋๋๋ก ํ ๊ฒ์ด๋ค.
1) ๋ธ๋ฃจํ๋ฆฐํธ ๊ตฌํ
๋จผ์ ๋ฐฐ์น๋ ์คํฐ ํฌ์ธํธ๋ค์ ๊ฐ์ ธ์ฌ ๊ฒ์ด๋ค. Get All Actors Of Class With Tag ๋ ธ๋๋ฅผ ํตํด ๋ ๋ฒจ์ ๋ฐฐ์น๋ ์กํฐ๋ค์ ๊ฐ์ ธ์ฌ ์ ์๋ค. Tag๋ฅผ ํตํด ํน์ Tag๋ฅผ ๊ฐ์ง ์กํฐ๋ง ๊ฐ์ ธ์ค๊ธฐ๋ ๊ฐ๋ฅํ๋ค.
๋ค์์ผ๋ก ์์ฑํ๊ณ ์ถ์ ์๋งํผ Loop๋ฅผ ๋๋ฉฐ ์กํฐ๋ฅผ ์์ฑํ๋ค.
- Collision Handling Override
- Always Spawn, Ignore Collisions: ์กํฐ๊ฐ ๋ค๋ฅธ ์ค๋ธ์ ํธ์ ์ถฉ๋ํด๋ ์ง์ ๋ ์์น์ ์์ฑํ๋ค
- Try To Adjust Location, But Always Spawn: ์ถฉ๋์ ํผํ๊ธฐ ์ํด ์กํฐ์ ์์น๋ฅผ ์กฐ์ ํ๋ ค๊ณ ์๋ํ๋ค. ๋ง์ฝ ์ถฉ๋์ ํผํ ์ ์๋ ์์น๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ฉด, ์ถฉ๋์ ๋ฌด์ํ๊ณ ์ง์ ๋ ์์น์ ์กํฐ๋ฅผ ์์ฑํ๋ค.
- Try To Adjust Location, Don't Spawn If Still Colliding: ์ถฉ๋์ ํผํ๊ธฐ ์ํด ์กํฐ์ ์์น๋ฅผ ์กฐ์ ํ๋ ค๊ณ ์๋ํ๋ค. ์ฌ์ ํ ์ถฉ๋์ด ๋ฐ์ํ๋ค๋ฉด, ์กํฐ๋ฅผ ์์ฑํ์ง ์๋๋ค.
- Do Not Spawn: ์ง์ ๋ ์์น์์ ์ถฉ๋์ด ๋ฐ์ํ๋ฉด ์กํฐ๋ฅผ ์์ฑํ์ง ์๋๋ค.
์์ฑ๋ ์กํฐ์ ์์น๋ ์ ์ฅํ ์คํฐ ํฌ์ธํธ์์ ๋๋คํ๊ฒ ํ๋๋ฅผ ๋ฝ๋๋ค. ๊ทธ ํ ์ค๋ณต๋ ์์น๊ฐ ๋์ง ์๋๋ก ๋ฝํ ์คํฐ ํฌ์ธํธ๋ ์ ๊ฑฐํ๋ค.
2) C++ ๊ตฌํ
UPROPERTY(EditDefaultsOnly)
TArray<TSubclassOf<AItem>> ItemClass;
#include "Kismet/GameplayStatics.h"
UGameplayStatics::GetAllActorsOfClassWithTag(GetWorld(), ASpawnPoint::StaticClass(), "Item", FoundActors);
for (AActor* a : FoundActors)
ItemSpawnPoints.Add(Cast<ASpawnPoint>(a));
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
SpawnParams.TransformScaleMethod = ESpawnActorScaleMethod::MultiplyWithRoot;
TArray<FTransform> SpawnPoints;
for (ASpawnPoint* a : ItemSpawnPoints)
SpawnPoints.Add(a->GetActorTransform());
int SpawnIndex = FMath::RandRange(0, SpawnPoints.Num() - 1);
AItem* Item = GetWorld()->SpawnActor<AItem>(ItemClass[0], SpawnPoints[SpawnIndex], SpawnParams);
SpawnPoints.RemoveAt(SpawnIndex);
2. Nav ๋ด ๋๋ค ์์น์ ์์ฑํ๊ธฐ
GetRandomReachablePointInRadius ๋ ธ๋๋ฅผ ํตํด origin์์ Radius ๋ด ๋๋ฌํ ์ ์๋ ๋๋คํ ์์น๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
1) ๋ธ๋ฃจํ๋ฆฐํธ ๊ตฌํ
2) C++ ๊ตฌํ
FTransform AMachine::GetRandomTransform(float Radius)
{
FNavLocation NavigationLocation;
UNavigationSystemV1::GetNavigationSystem(GetWorld())->GetRandomReachablePointInRadius(EnemySpawnPoint->GetComponentLocation(), Radius, NavigationLocation);
return UKismetMathLibrary::MakeTransform(NavigationLocation, UKismetMathLibrary::FindLookAtRotation(NavigationLocation, EnemySpawnPoint->GetComponentLocation()));
}