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"

Why can't we use TArray of TWeakObjectPtr from C++ to blueprint ?

Hi,

Consider this kind of code :

 UCLASS(Blueprintable)
 class GAME_API ACustomActor : public AActor
 {
    GENERATED_BODY()
 
 public:
     UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "My Cat")
     TArray< TWeakObjectPtr<AAnotherSubActor> > listOfStuff;
 }

I get a compilation error like this :

error : Type 'TArray' is not supported by blueprint.

My goal is to create a blueprint from that Cpp Class, to add meshes and basic logic more easely than writting every thing, and I keep Cpp for more advanced/algorythmic stuff.

Obviously I don't want to deal with dangling pointer in my arrays, as I allow those arrays to be filled by in blueprint or in the editor. TWeakObjectPtr seamed to be the perfect wrapping class, I could use IsValid() to be sure of the state of my Actors etc.

I guess from the very few other threads talking about that, if I use a TArray< Actor *> it will work, but isn't it a nightmare to manipulate an array of raw object my class don't have ownership of and that can be destroyed anywhere else in the engine ?

What would be a better, or at least more common approach in unreal guide lines here ? Thanks

Product Version: UE 4.15
Tags:
more ▼

asked May 21 '17 at 02:46 PM in C++ Programming

avatar image

yann.torres
3 1 2 3

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

1 answer: sort voted first

TWeakObjectPtr type is not supported by reflection system or blueprint itself, this type was made for use outside of it (for example Slate which powers UMG as it complitly outside reflection system). All variables visible to engine with UPROPERTY() are already managed, they will automatically null pointers to all properly deleted UObjects, so no need to use those special pointer types on UPROPERTY() variables (or else some specific container type don't cooperate with garbage collection, but all blueprint supported type should)

more ▼

answered May 21 '17 at 03:19 PM

avatar image

Shadowriver
35.9k 929 169 1105

avatar image yann.torres May 21 '17 at 03:42 PM

Oh !

That also works for the content of TArrays ? I mean, if I add some SubActorA into an array that is a UProperty of my SubActorB class (like this TArray) and then, if the engine or editor or anyone else delete one of the elements of this array without notifying my SubActorB, the element will still be set to null instead of an dungling ptr ?

avatar image Shadowriver May 21 '17 at 04:40 PM

Sry i was wrong a bit, it does not remove or null the pointer, instead it keeps actor alive in memory until it's removed, and then you can check IsPandingKill

https://docs.unrealengine.com/latest/INT/API/Runtime/CoreUObject/UObject/UObjectBaseUtility/IsPendingKill/index.html

Bluepritn Array is TArray, so you can experiment via blueprinting how array and object behaves in such case

avatar image yann.torres May 21 '17 at 04:50 PM

oki, I'm going to bootstrap a small project to test that behavior. Having an actor that possess an array of other actors seams to be an extremly common use case into a game, it would be surprising that cpp to blueprint can't handle that use case. Thank you for your response

avatar image yann.torres May 21 '17 at 07:01 PM

ok I did the test, and you were right it is set to Null. The workflow when actor is destroyed by some action is :

  • Actor Destroyed() is immediately called, and mesh or other visual things immediately disapears

  • At that moment array pointer still point to the valid actor that can be used

  • One minute later, GC come through

  • Actor destructor is called

  • Array is still the same size, but ptr of the concerned array element is NULL

I can then use raw pointers for UObjects at least.

avatar image Shadowriver May 21 '17 at 07:03 PM

Alright, so i was right after all :) sry i only test on blueprint as it a lot easier to test there

avatar image kamrann Jan 17 '18 at 03:22 AM

I just want to add to this, since I just hit the same issue.

First to clarify, the reflection system does support TWeakObjectPtr, it is specifically the BlueprintReadWrite/Only specifiers that are incompatible,

The behaviour you list here is exactly why I use TWeakObjectPtr extensively (in both UPROPERTY and non-UPROPERTY contexts), especially for actors and components which are different from most UObjects in that they are frequently destroyed directly. By doing so, I never in any of my UE4 coding have cause to mess around with low level functions like IsValid or IsPendingKill, because weak object pointers become invalid the moment an object is marked for kill. Managed raw pointers on the other hand are only cleaned up later when the GC runs, meaning you really need to use IsPendingKill pretty much any time you want to access them. It's not strictly a dangling pointer, but from a behaviour point of view it's still dangerous not to check.

So essentially, just saying I think this is a very valid question, and the lack of support for TWeakObjectPtrin blueprints is a pain!

avatar image BrUnO XaVIeR Jan 17 '18 at 11:51 AM

TSoftObjectPtr is supported by Blueprints:

 UPROPERTY(Category = Default, EditAnywhere, BlueprintReadWrite)
     TSoftObjectPtr<AActor> SomePtr; //SomePtr.Get();
avatar image kamrann Jan 17 '18 at 01:18 PM

Interesting. Technically that's meant for objects with a persistent path (assets, or placed actors in a map file) that can be reloaded if they drop out of memory. Since that doesn't apply to dynamically spawned actors, it feels a little hacky, but if blueprint lets you do it then I'd probably prefer it to a raw pointer.

Given that TSoftObjectPtr is implemented as a weak pointer + asset path, it kind of confirms that there's no good reason why Blueprint shouldn't support regular weak object pointers.

(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