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 while drawing HUD

Hi,

in my current C++ Project I try to create a custom HUD. I want to mark important actors on the screen.

I extended AHUD and in the DrawHUD() function, I draw a marker Material and a Text for each object. The following is the code of my HUD class:

 // In ShipHUD.h
 UCLASS()
 class AShipHUD : public AHUD
 {
     GENERATED_UCLASS_BODY()
 
     void BeginPlay() override;
     void DrawHUD() override;
 
 protected:
     UPROPERTY(Category = Marker, EditAnywhere)
     float MarkerSize;
 
     UPROPERTY(Category = Marker, EditAnywhere)
     float MarkerFontScale;
 
 private:
     struct FMarkerType
     {
         UMaterialInstance* Material;
         FLinearColor Color;
 
         FMarkerType() : Material(nullptr), Color(FLinearColor::White) { }
         FMarkerType(UMaterialInstance* Material, const FLinearColor& Color) :
             Material(Material), Color(Color) { }
     };
 
     void AddMarkerType(ERelationship Relationship, UMaterial* BaseMaterial, 
          const FLinearColor& Color);
 
     UPROPERTY() UFont* Font;
 
     /// Multiple instances of the same marker material with 
     /// different colors for friendly / neutral / hostile
     TMap<ERelationship, FMarkerType> MarkerTypes;
 
     /// This array just prevents the MaterialInstances from being garbage collected
     TArray<UMaterialInstance*> MarkerInstances;
 
     TWeakObjectPtr<AShip> Ship;
 };

 // In ShipHUD.cpp
 AShipHUD::AShipHUD(const class FPostConstructInitializeProperties& PCIP)
     : Super(PCIP),
     MarkerSize(16.f),
     MarkerFontScale(0.6f)
 {
     static ConstructorHelpers::FObjectFinder<UMaterial> MarkerMaterialOb(TEXT("/Game/UI/HUD/M_Marker"));
     static ConstructorHelpers::FObjectFinder<UFont> FontOb(TEXT("/Engine/EngineFonts/RobotoDistanceField"));
     
     // Markers
     if(MarkerMaterialOb.Succeeded() && GEngine)
     {
         AddMarkerType(ERelationship::NEUTRAL, MarkerMaterialOb.Object, FLinearColor::White);
         AddMarkerType(ERelationship::HOSTILE, MarkerMaterialOb.Object, FLinearColor::Red);
         AddMarkerType(ERelationship::FRIENDLY, MarkerMaterialOb.Object, FLinearColor::Green);
     }
 
     if(FontOb.Succeeded())
     {
         Font = FontOb.Object;
     }
 }
 
 void AShipHUD::BeginPlay()
 {
     AHUD::BeginPlay();
     Ship = Cast<AShip>(GetOwningPawn());
 }
 
 void AShipHUD::DrawHUD()
 {
     AHUD::DrawHUD();
 
     // Target points
     ASunAndStarsGameState* GameState = GetWorld()->GetGameState<ASunAndStarsGameState>();
     AShipPlayerController* Controller = 
         Cast<AShipPlayerController>(GetOwningPlayerController());
     if(GameState && Controller && Ship.IsValid())
     {
         uint32 PlayerTeam = Ship->GetTeam();
         for(auto It = Controller->GetTrackedObjects().CreateConstIterator(); It; ++It)
         {
             AActor* Object = It->Get();
             ERelationship Relationship = ERelationship::NEUTRAL;
             
             // See if the object has a team. If this is the case, color marker accordingly
             ITeamAssignable* TeamAssignable = InterfaceCast<ITeamAssignable>(Object);
             if(TeamAssignable)
             {
                 uint32 ObjectTeam = TeamAssignable->GetTeam();
                 Relationship = GameState->Diplomacy->GetRelationship(PlayerTeam, ObjectTeam);
             }
 
             FVector ObjectLocation = Object->GetActorLocation();
             FVector ScreenCoordinates = Project(ObjectLocation);
             if(ScreenCoordinates.Z != 0.f)
             {
                 // Target point is on screen. Draw the following for each target: 
                 // A crosshair marker and the name of the object with the current distance.
                 // ####### The game crashes here! ########
                 DrawMaterialSimple(MarkerTypes[Relationship].Material,
                     ScreenCoordinates.X - MarkerSize / 2, 
                     ScreenCoordinates.Y - MarkerSize / 2, 
                     MarkerSize, 
                     MarkerSize);
                 DrawText(FString::Printf(TEXT("%s (%s)"), *Object->GetName(), 
                        *FUnrealDistance::Format(Ship->GetActorLocation(), ObjectLocation)),
                     MarkerTypes[Relationship].Color,
                     ScreenCoordinates.X + MarkerSize,
                     ScreenCoordinates.Y - Font->GetMaxCharHeight() * MarkerFontScale / 2,
                     Font,
                     MarkerFontScale);
             }
         }
     }
 }
 
 inline void AShipHUD::AddMarkerType(ERelationship Relationship, UMaterial* BaseMaterial, 
     const FLinearColor& Color)
 {
 UMaterialInstanceDynamic* MaterialInstance = 
         UMaterialInstanceDynamic::Create(BaseMaterial, this);
 MarkerInstances.Add(MaterialInstance);
 MaterialInstance->SetVectorParameterValue(TEXT("Color"), Color);
 MarkerTypes.Add(Relationship, FMarkerType(MaterialInstance, Color));
 }

When I run the code, everything is fine, it works and I see the markers. But every time after exactly 60 Seconds, the application crashes with the following error message:

Unhandled exception at 0x00007FFB10CBC3AA (UE4Editor-Engine-Win64-Debug.dll) in UE4Editor-Win64-Debug.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

According to the debugger, it crashes in Line 587 of Runtime/Engine/Private/HUD.cpp (I am working with the full source code version from GitHub). This is the function DrawMaterialSimple() I call in my HUD class (I marked the line in the code).

I don't know what's going on here. I already tried to check all memory allocations, but the fact that the program works well for 60 Seconds leads me to believe that it might be the Garbage Collector that deletes an object from right under me. But I think I made every relevant Object a UPROPERTY() Reference, so the GC should not delete it, right?

I don't know how I can find out more about what I am doing wrong. I would really appreciate any help or guidance to solve the problem.

Thanks in advance and sorry for the long post

David

Product Version: Not Selected
Tags:
more ▼

asked Oct 20 '14 at 09:34 AM in C++ Programming

avatar image

Oromis
18 5 7 10

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

1 answer: sort voted first

Try making your MarkerInstances array a UPROPERTY() - your comment claims it's to keep them referenced to avoid GC, but the array needs to be a UPROPERTY() for that to happen.

more ▼

answered Oct 20 '14 at 09:38 AM

avatar image

Jamie Dale STAFF
7.4k 176 66 304

avatar image Oromis Oct 20 '14 at 09:40 AM

Yeah, I found the answer like 2 Minutes after I posted but I couldn't post an answer somehow. But thanks for your help and for making it clear to others what the problem was!

avatar image Jamie Dale STAFF Oct 20 '14 at 09:45 AM

Your question contained a word blacklisted by our word filter (the American slang term for your bottom, or a British term for a Donkey), so it went to moderation :)

avatar image Oromis Oct 20 '14 at 09:47 AM

Ah I see :) Sorry for that!

(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