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"

No longer able to call Blueprint Events on CDOs

As of 4.16, if you have a simple class like such:

 UCLASS(Blueprintable)
 class UMyBlueprintObject : public UObject
 {
    GENERATED_BODY()
 public:
    UMyBlueprintObject();
 
    UFUCTION(BlueprintImplementableEvent, Category = "Foo")
    void Bar() const;
 };

Create a blueprint version that adds logic to the Bar event (even a simple PrintString), and then simply call the event on the CDO (either through another blueprint or simply grabbing it through C++) of that new Object:

 TSubClassOf<UMyBlueprintObj> MyDerivedClass; // Set this in the editor or what not.
 MyDerivedClass->GetDefaultObject->Bar();

You'll get the following error:

Ensure condition failed: PointerToUberGraphFrame->RawPointer [File:D:\_perforce\Vendor\UE\UnrealEngine-4.16.0-release\Engine\Source\Runtime\Engine\Private\BlueprintGeneratedClass.cpp] [Line: 1094]

Which comes from this method:

 uint8* UBlueprintGeneratedClass::GetPersistentUberGraphFrame(UObject* Obj, UFunction* FuncToCheck) const
 {
     if (Obj && UsePersistentUberGraphFrame() && UberGraphFramePointerProperty && UberGraphFunction)
     {
         if (UberGraphFunction == FuncToCheck)
         {
             FPointerToUberGraphFrame* PointerToUberGraphFrame = UberGraphFramePointerProperty->ContainerPtrToValuePtr<FPointerToUberGraphFrame>(Obj);
             checkSlow(PointerToUberGraphFrame);
             ensure(PointerToUberGraphFrame->RawPointer); // <- Crash due to assert
             return PointerToUberGraphFrame->RawPointer;
         }
     }
     UClass* ParentClass = GetSuperClass();
     checkSlow(ParentClass);
     return ParentClass->GetPersistentUberGraphFrame(Obj, FuncToCheck);
 }

That seems to be related to this change that came in from Fortnite:

 void UBlueprintGeneratedClass::CreatePersistentUberGraphFrame(UObject* Obj, bool bCreateOnlyIfEmpty, bool bSkipSuperClass, UClass* OldClass) const
 {
     if (Obj && Obj->HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject)) // <- Added in 4.16
     {
         return; // <- No Persistent Uber Graph Frame is created for CDOs.
     }


Change 3238782 on 2016/12/16 by Ben.Zeigler (Integrated into mainline with 4.16)

 #jira FORT-34825 Fix issue where Macro CDOs had corrupted persistent ubergraph frames during blueprint compile on load, by changing it so no CDOs have persistent frames.
 This also saves memory as using persistent frames is incorrect for CDOs, things like latent functions do not make sense.
 Fix from Dan O'Connor


Removing that added logic fixes the functionality that existed pre-4.16. Is there another way to manually allow a CDO to call overridden script methods?

CDOs are a convenient way to basically enforce a Singleton-esque pattern and keep down memory usage. If blueprint events are no longer allowed on CDOs - then that's going to increase memory usage as all objects with blueprint events will now have to be instantiated so they can get their PersistantUberGraphFrame.

Cheers,

  • Matt

Product Version: UE 4.16
Tags:
more ▼

asked Jun 23 '17 at 12:32 AM in Bug Reports

avatar image

ExtraLifeMatt
1.4k 31 10 43

avatar image Doug E ♦♦ STAFF Jun 23 '17 at 05:31 PM

Hey ExtraLifeMatt-

I'm having some difficulity following your code. Where are you adding the lines

TSubClassOf MyDerivedClass; MyDerivedClass->GetDefaultObject->Bar();?

Is this part of UMyBlueprintObject class or are you adding this to another class you created? If so, which function are you calling MyDerivedClass->GetDefaultObject->Bar(); from? Is there anything else in the source file of your UObject class?

avatar image ExtraLifeMatt Jun 23 '17 at 06:46 PM

Sorry, for the confusion.

You can add the MyDerivedClass field to some other class that you can access from the editor ,(i.e. ThirdPersonCharacter or some such):

 // In the ThirdPersonCharacter code
 
 //.h
 
 UPROPERTY(EditAnywhere, Category = "Foobar")
 TSubClassOf<UMyBlueprintObj> MyBlueprintObject;
 
 // .cpp, in some place like OnBeginPlay
 
 MyBlueprintObject->GetDefaultObject()->Bar();


Then simply drop in a character, and set the property on the character.

There's nothing else in the source file or such.

avatar image ExtraLifeMatt Jun 26 '17 at 04:21 PM

@Doug Wilson

Where you able to repro this? Do you need anything else from me?

avatar image Doug E ♦♦ STAFF Jun 26 '17 at 05:26 PM

When I try to use the line MyBlueprintObject->GetDefaultObject()->Bar(); I receive a compile error that 'class "UObject" has no member "Bar"'. It appears that MyBlueprintObject->GetDefaultObject() is returning UObject rather than UMyObject, so it doesn't see the Bar() function from my class. Please provide a small repro project to help investigate the crash you're seeing

avatar image ExtraLifeMatt Jun 26 '17 at 05:31 PM

Just toss a cast in there:

 Cast<UMyBlueprintObj>(MyBlueprintObject->GetDefaultObject())->Bar();

If that doesn't work, I'll get you a small repro project tonight.

avatar image Doug E ♦♦ STAFF Jun 26 '17 at 06:09 PM

After adding in the cast I was able to compile successfully and when I played in the editor the print string from my blueprinted Bar function appeared as expected.

avatar image ExtraLifeMatt Jun 26 '17 at 06:24 PM

Alrighty, I'll try and get a repro project to you tonight.

avatar image ExtraLifeMatt Jun 27 '17 at 02:09 AM

Alright @Doug Wilson,

Here is a test project that shows the issue. There's two Blueprint objects in the ThirdPersonCPP/Blueprints folder. CrashBP will cause the crash, SafeBP will not. There is a field named "Foobar" on the Character in the level that is currently set to CrashBP, hitting Play will cause the assert/crash.

The only difference between how these two classes are created is CrashBP was created with Blueprint Editor option "Spawn Default Event Nodes" turned on (and Bar made into a default event through the config files), and SafeBP had that option disabled.

Default spawned event nodes take a different compiler path than non-default spawned events (they end up getting merged into the new blueprint), which is causing them to call FKismetCompilerContext::CreateFunctionStubForEvent and that in turn eventually calls UBlueprintGeneratedClass::CreatePersistentUberGraphFrame which had its logic changed by the Changelist I reference in the original post.

The work around is to simply disable the "Spawn Default Event Nodes" option in the Blueprint Editor, but that's less than ideal.

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

2 answers: sort voted first

After discussion, we decided to bring back the persistent ubergraph frames for CDOs other than Macro Libraries. This fix should be in a future hotfix, to fix this problem locally change the return condition at the top of CreatePersistentUberGraphFrame to this:

 UBlueprint* Blueprint = Cast<UBlueprint>(ClassGeneratedBy);
 if (Blueprint && Blueprint->BlueprintType == BPTYPE_MacroLibrary)
 {
     return;
 }
more ▼

answered Jun 27 '17 at 07:30 PM

avatar image

Ben Zeigler
286 3 4 23

avatar image ExtraLifeMatt Jun 27 '17 at 08:20 PM

Thanks, sounds good Ben!

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

Hey ExtraLifeMatt-

Thank you for the sample project. I have reproduced this issue and logged a report for it here https://issues.unrealengine.com/issue/UE-46534 . You can track the report's status as the issue is reviewed by our development staff. Please be aware that this issue may not be prioritized or fixed soon.

Cheers

Doug Wilson

more ▼

answered Jun 27 '17 at 02:21 PM

(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