Actor 가 스폰될 지점에 캐릭터가 미리 가서 대기타고있으면 Trigger 가 발동되지 않는 문제가 발생한다.

원래대로라면 나머지 상자들도 사라져야하는데 사라지지 않음 -> Delegate 발동이 되지 않음.
void AABStageGimmick::SpawnRewardBoxes()
{
for (auto& RewardBoxLocation : RewardBoxLocations)
{
FVector Location = GetActorLocation() + RewardBoxLocation.Value + FVector::UpVector * 30.f;
AABItemBox* Box = GetWorld()->SpawnActor<AABItemBox>(RewardBoxClass, Location, FRotator::ZeroRotator);
if (Box)
{
Box->Tags.Add(RewardBoxLocation.Key);
Box->GetTrigger()->OnComponentBeginOverlap.AddDynamic(this, &AABStageGimmick::OnRewardTriggerBeginOverlap);
Box->GetTrigger()->OnComponentHit.AddDynamic(this, &AABStageGimmick::OnRewardTriggerHit);
//Box->GetTrigger()->oncomponent
RewardBoxes.Add(Box);
}
}
}
그 이유는 동작 순서가 1. 생성 2. Collision 반응 시 삭제 인데, 미리 가있으면 생성만 하고 Collision 반응을 할 Delegate 호출까지 하지 않는 듯 하다.
해결방법
- Actor 의 충돌감지를 Overlap 이 아닌 Hit 으로 바꿈. (필요에 따라 Collision 의 Preset 추가를 해줘야 함), 그리고나서 SpawnCollisionHandlingOverride 를 이용해 아래와같이 소환지점에 캐릭터와 충돌하는지의 여부를 결정해 스폰.
void AABStageGimmick::SpawnRewardBoxes()
{
for (auto& RewardBoxLocation : RewardBoxLocations)
{
FVector Location = GetActorLocation() + RewardBoxLocation.Value + FVector::UpVector * 30.f;
FActorSpawnParameters Params;
Params.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
AABItemBox* Box = GetWorld()->SpawnActor<AABItemBox>(RewardBoxClass, Location, FRotator::ZeroRotator, Params);
if (Box)
{
Box->Tags.Add(RewardBoxLocation.Key);
//Box->GetTrigger()->OnComponentBeginOverlap.AddDynamic(this, &AABStageGimmick::OnRewardTriggerBeginOverlap);
Box->GetTrigger()->OnComponentHit.AddDynamic(this, &AABStageGimmick::OnRewardTriggerHit);
RewardBoxes.Add(Box);
}
}
}

어거지로 스폰할경우 위와같이 생성됨. Overlap 을 사용했을 시 발생할 수 있는 버그같은 동작을 미연에 방지할 수 있어 더 좋은것 같다.
##수정
SpawnActor() 함수가 아닌 지연생성함수 SpawnActorDeffered() 를 사용하면 위의 문제를 원천적으로 차단할 수 있다는 것을 알게되어 위의 방법이 굳이 필요가 없어졌다.
void AABStageGimmick::SpawnRewardBoxes()
{
for (auto& RewardBoxLocation : RewardBoxLocatoins)
{
FVector WorldSpawnLocation = GetActorLocation() + RewardBoxLocation.Value + FVector(0.f, 0.f, 30.f);
FTransform Transform1(WorldSpawnLocation);
AABItemBox* ItemActor = GetWorld()->SpawnActorDeferred<AABItemBox>(RewardBoxClass, Transform1);
if (ItemActor)
{
//RewardBoxActor->Tags.Add(RewardBoxLocation.Key);
ItemActor->GetTrigger()->OnComponentBeginOverlap.AddDynamic(this, &AABStageGimmick::OnRewardTriggerBeginOverlap);
UE_LOG(LogTemp, Log, TEXT("DelegateAfter"));
RewardBoxes.Add(ItemActor);
}
}
for (const auto& RewardBox : RewardBoxes)
{
if (RewardBox.IsValid())
{
RewardBox.Get()->FinishSpawning(RewardBox.Get()->GetActorTransform());
}
}
}
일반적인 SpawnActor 일 경우 생성되자마자 ->Constructor, BeginPlay 등등으로 동시에 ItemBox 만의 Trigger 가 바로 설정되어 아래 기믹의 트리거가 설정되기도 전에 먼저 트리거가발동되어 예기치 않은 문제가 발생할 수 있음.
-> 기믹의 트리거가 먼저 설정되고 나서 아이템의 트리거가 설정되어야 하니, SpawnActorDeferred 가 필요한 것.

`
