x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to check for number of AActors within a SpawnVolume?

Hi

I have created a Object Spawner in C++.

The problem is however it infinitely spawns objects of subclass of type AActor. The logic that I am trying to implement is that if there is less than property of maxObjects then it will spawn up until this number.

Here is a snippet of the code however it doesn't seem to work. http://i.imgur.com/B4veHnH.png

Apologies if this is an obvious question. I have been stuck on this for several days and I cannot seem to get it working.

I have a blueprint version of the spawner which works fine but I am being marked on my C++ implementation.

Kind Regards and Many Thanks

Product Version: UE 4.12
Tags:
more ▼

asked Mar 06 '17 at 01:32 PM in C++ Programming

avatar image

LittleBigProgramming
1 3 4 5

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

That code seems fine to me, but perhaps GameplayStatics isn't returning what you think it is? Have you placed a breakpoint and seen how many entries its returning?

Another solution you could do is just manage that list yourself.

 TArray<TWeakObjPtr<AActor>> MySpawnedActors; // Add this in your class somewhere.
 
 // ... in your spawning code:
 
 // Check our spawned actors and see if any were destroyed before we attempt to allocate anymore...
 
 // This looks nasty but its just a predicate (a locally defined function) that removes all entities that are no longer valid
 MySpawnedActors.RemoveAll([ ] (TWeakObjPtr<AActor>& SpawnedActor)
 {
   return !SpawnedActor.IsValid();
 });
 
 if (MySpawnedActors.Num() < MaxSpawnedActors)
 {
   // Spawn a new actor.
   AActor* NewActor = World->SpawnActor(...);
   MySpawnedActors.Add(NewActor);
 }
more ▼

answered Mar 06 '17 at 03:10 PM

avatar image

ExtraLifeMatt
1.5k 34 14 48

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

I don't think the problem you're having is in the code snippet you posted. I just tried this (with the obvious header and the latest build from master, but that should not matter):

 AGeneralSpawnVolume::AGeneralSpawnVolume()
     : MaxSpawnedObjects{ 5 }
     , MinSpawnDelay{ 1.f }
     , MaxSpawnDelay{ 4.f }
 {
 }
 
 void AGeneralSpawnVolume::BeginPlay()
 {
     SpawnPickup();
 }
 
 void AGeneralSpawnVolume::SpawnPickup()
 {
     TSubclassOf<AActor> ClassToFind{ AStaticMeshActor::StaticClass() };
     TArray<AActor*> FoundActors;
     UWorld* World = GetWorld();
     check(World);
 
     UGameplayStatics::GetAllActorsOfClass(World, ClassToFind, FoundActors);
 
     if (FoundActors.Num() <= MaxSpawnedObjects)
     {
         UE_LOG(LogTemp, Warning, TEXT("%d <= %d: Spawning a new actor"), FoundActors.Num(), MaxSpawnedObjects);
         AActor* SpawnedPickup{ World->SpawnActor<AActor>(AStaticMeshActor::StaticClass(), GetActorLocation(), GetActorRotation()) };
     }
     else
     {
         UE_LOG(LogTemp, Warning, TEXT("%d > %d: Not spawning a new actor"), FoundActors.Num(), MaxSpawnedObjects);
     }
 
     float SpawnDelay{ FMath::FRandRange(MinSpawnDelay, MaxSpawnDelay) };
     GetWorldTimerManager().SetTimer(SpawnTimer, this, &AGeneralSpawnVolume::SpawnPickup, SpawnDelay, false);
 }

and it works as expected:

 LogTemp:Warning: 1 <= 5: Spawning a new actor
 LogTemp:Warning: 2 <= 5: Spawning a new actor
 LogTemp:Warning: 3 <= 5: Spawning a new actor
 LogTemp:Warning: 4 <= 5: Spawning a new actor
 LogTemp:Warning: 5 <= 5: Spawning a new actor
 LogTemp:Warning: 6 > 5: Not spawning a new actor
 LogTemp:Warning: 6 > 5: Not spawning a new actor
 LogTemp:Warning: 6 > 5: Not spawning a new actor

(You need to initialize the ClassToFind variable, otherwise you'll spawn new actors indefinitely since GetAllActorsOfClass returns an empty array when you pass a null pointer as class to find.)

There are two places where I would start looking for the error:

  • Is it possible that you set ClassToFind to a class that has more instances than you expect? For example, if you set it to AActor::StaticClass() you get all actors in the level, which are probably many more than your value of mMaxSpawnedObjects.

  • Do you actually call the method again once have reached the mMaxSpawnedObjects for the first time? You're only setting the timer if you spawn something, so the first time you don't spawn anything because there are enough actors in the level your spawn volume becomes inactive until it is reactivated again.

more ▼

answered Mar 06 '17 at 03:30 PM

avatar image

Matthias Hölzl
416 13 6 19

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question