MiddleКодЧастоЕщё не отвечали
Напишите функцию на C++, которая спавнит AActor в заданной позиции в Unreal Engine.
Напишите функцию, которая спавнит Actor заданного класса в заданной мировой позиции. Используйте штатный API спавна движка, чтобы Actor был корректно зарегистрирован для тика, репликации и BeginPlay.
Требования:
(задайте владельца; выберите режим обработки столкновений).
указатель на null — спавн может не удаться, если обработка столкновений отвергнет место.
- Спавните через
UWorld::SpawnActor<T>— а не черезNewObjectилиnew. - Постройте
FTransformиз позиции и передайтеFActorSpawnParameters - Проверьте
World/ActorClassна null заранее и проверьте возвращённый
Допишите тело функции:
AActor* SpawnAt(UWorld* World, TSubclassOf<AActor> ActorClass,
const FVector& Location, AActor* Owner)
{
// ваш код здесь
}
Допишите реализацию.
Вызовите GetWorld()->SpawnActor<T>(Class, Transform, Params). Постройте FTransform из позиции, передайте FActorSpawnParameters и всегда проверяйте возвращённый указатель на null — спавн может не удаться, если тест столкновений отвергнет позицию.
- ✗Использовать
NewObjectилиnewдля Actor — Actor создаётся только черезSpawnActor - ✗Не проверять результат на null — спавн не удаётся, когда обработка столкновений отвергает место
- ✗Забывать, что
BeginPlayвыполняется как часть спавна, а не до него
- →Что контролирует
ESpawnActorCollisionHandlingMethodво время спавна? - →Как отложенный спавн позволяет задать свойства до
BeginPlay?
Спавн Actor в заданной позиции
AActor* SpawnAt(UWorld* World, TSubclassOf<AActor> ActorClass,
const FVector& Location, AActor* Owner)
{
if (!World || !ActorClass)
{
return nullptr;
}
// Трансформация: позиция, единичный поворот, единичный масштаб
const FTransform SpawnTransform(FRotator::ZeroRotator, Location);
FActorSpawnParameters Params;
Params.Owner = Owner;
// Сдвинуть Actor, если позиция перекрыта геометрией
Params.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
AActor* Spawned = World->SpawnActor<AActor>(ActorClass, SpawnTransform, Params);
// Спавн может вернуть nullptr, если выбран режим, отменяющий спавн
if (!Spawned)
{
UE_LOG(LogTemp, Warning, TEXT("SpawnAt: спавн не удался"));
}
return Spawned;
}
Ключевые моменты:
- Actor создаётся только через
UWorld::SpawnActor—NewObjectилиnewне зарегистрируют его для тика, репликации иBeginPlay. BeginPlayвызывается внутриSpawnActor(для миров, где игра уже идёт) — к моменту возврата Actor уже инициализирован.- Результат нужно проверять: при
ESpawnActorCollisionHandlingMethod::DontSpawnIfCollidingфункция вернётnullptr. - Если свойства нужно задать до
BeginPlay, используйте отложенный спавн:SpawnActorDeferred<T>(...), затемFinishSpawning(Transform).