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"

Crash on 'Stop Simulation'

Ok, so I am really hitting a wall here and I figured I might as well ask since I have seen no mention of a similar problem after extensive research throughout forums.

I have a class called AS_BoardPawn inheriting from the APawn class and I need to spawn a Blueprint object derived from a C++ class which is a simple mesh that is spawned when the player clicks a spot on the screen and is destroyed when the player releases the click. I found information on how to spawn said Blueprint class and it works as it should, however for some reason under two circumstances the editor crashes.

  1. When I click "Stop Simulation"

  2. When I wait while the mesh is on the screen (about 1-2 minutes, probably garbage collection ?)

When debugging with VS I get an Exception in UObjectBase.h at line 125

 FORCEINLINE UObject* GetOuter() const
 {
     return OuterPrivate;
 }

Now, my assumption is that UE4 is accessing a stale pointer which leads to one of my classes (the Pawn class ?) but I have no idea how to fix this, I've tried quite a few things, but nothing seems to work.

The function for spawning the actor :

 AEffectLine* AS_BoardPawn::SpawnEffectLine(FVector location) 
 {
     AEffectLine* newEffectLine = 0;
 
     if (effectLine)
     {
         FActorSpawnParameters SpawnParams;
 
         FRotator rotator = FRotator(0.0f);
 
         newEffectLine = GetWorld()->SpawnActor<AEffectLine>(effectLine, location, rotator, SpawnParams);
     }
 
     return newEffectLine;
 }

with effectLine being a UClass* (I changed it from SubClassOf after seeing mentions of it causing issues, but to no avail)

If it can be of any help, here is the whole Tick function where effectLineInst is a AEffectLine* and selectionLines is a TArray of AEffectLine*

 void AS_BoardPawn::Tick(float DeltaTime)
 {
     Super::Tick(DeltaTime);
 
     if (clicking) 
     {
         //Update effectLine
         if (effectLineInst) 
         {
             playerCtrl->DeprojectMousePositionToWorld(mouseLocation, mouseDirection);
 
             projMousePosition = this->GetActorLocation() - (projHeight / mouseDirection.Z) * mouseDirection;
 
             AEffectLine* eLine = Cast<AEffectLine>(effectLineInst);
             if (eLine != nullptr) 
             {
                 eLine->UpdateSplineSimple(projMousePosition);
             }
         }
 
         clickingUpdate = true;
 
         if (selectedLamps.Num() <= loopLength)
         {
             //Gets the hit result of objects under the mouse
             FHitResult* hit = new FHitResult;
             playerCtrl->GetHitResultUnderCursor(ECC_WorldStatic, false, *hit);
             AActor* hitActor = hit->GetActor();
 
             bool debugBool = selectedLamps.Contains(hitActor);
 
             //Check if the lamp is valid and not already in the array
             if (hitActor && hitActor->IsA(ALamp::StaticClass()) && (!selectedLamps.Contains(hitActor) && 
                 selectedLamps.Num() < loopLength || selectedLamps.Num() > 0 && hitActor == selectedLamps[0] && hitActor != selectedLamps.Last()))
             {
                 bool isClear = false;
                 if (selectedLamps.Num() > 0)
                 {
                     FHitResult* pathHit = new FHitResult;
                     //Line trace between the last lamp and the new one to find if path is clear
                     FVector Start = selectedLamps.Last()->GetActorLocation();
                     FVector End = hitActor->GetActorLocation();
 
                     if (FVector::DistSquared(Start, End) < 9000000.0f)
                     {
                         FCollisionQueryParams* TraceParams = new FCollisionQueryParams();
 
                         ALamp* Startlamp = Cast<ALamp>(selectedLamps.Last());
 
                         Startlamp->SetActorEnableCollision(false);
                         isClear = !GetWorld()->LineTraceSingleByChannel(*pathHit, Start, End, ECC_WorldStatic, TraceParams);
                         Startlamp->SetActorEnableCollision(true);
 
                         if (pathHit->GetActor() && pathHit->GetActor()->IsA(ALamp::StaticClass()))
                             isClear = true;
                     }
                 }
                 else
                 {
                     isClear = true;
                 }
 
                 if (isClear) //The lamp selection is validated
                 {
                     ALamp* lamp = Cast<ALamp>(hitActor);
                     lamp->SetLampState(true);
 
                     selectedLamps.Add(hitActor);
 
                     FVector lampLocation = hitActor->GetActorLocation();
 
                     if (effectLineInst) 
                     {
                         AEffectLine* eLine = Cast<AEffectLine>(effectLineInst);
                         if (eLine != nullptr) 
                         {
                             eLine->UpdateSplineSimple(FVector(lampLocation.X, lampLocation.Y, effectLineHeight));
                         }
                         selectionLines.Add(effectLineInst);
                     }
                     
                     effectLineInst = SpawnEffectLine(FVector(lampLocation.X, lampLocation.Y, effectLineHeight));
                 }
             }
         }
     }
     else if (clickingUpdate)
     {
         clickingUpdate = false;
 
         //If loop was not completed
         if (selectedLamps.Num() > 0 && selectedLamps.Last() != selectedLamps[0]) 
         {
             //Turns off lamps
             uint8 arrayLength = selectedLamps.Num();
             for (uint8 i = 0; i < arrayLength; ++i) 
             {
                 ALamp* lamp = Cast<ALamp>(selectedLamps[i]);
                 lamp->SetLampState(false);
             }
 
             //Clears electric lines
             arrayLength = selectionLines.Num();
             for (uint8 i = 0; i < arrayLength; ++i)
             {
                 if (selectionLines[i]) 
                 {
                     selectionLines[i]->Destroy();
                 }
             }
         }
 
         if (effectLineInst)
         {
             effectLineInst->Destroy();
         }
 
         delete effectLineInst;
         effectLineInst = 0;
 
         selectedLamps.Empty();
     }
 }

It's probably also worth mentioning that all class variables are declared with UPROPERTY

I am really at a loss here, thank you in advance

Product Version: UE 4.21
Tags:
more ▼

asked Jan 26 '19 at 01:15 AM in C++ Programming

avatar image

Onirael
1

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Finally fixed the issue, it was actually totally unrelated to the code itself, turns out I had a pawn already spawned in the editor and UE4 spawned another pawn when starting the game, which caused the crash (two pawns existing at the same time reacting to the same input and spawning/destroying at the same time)

more ▼

answered Feb 07 '19 at 06:27 PM

avatar image

Onirael
1

(comments are locked)
10|2000 characters needed characters left
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