Enforce TObjectPtr! (And how to avoid pitfalls)

As on Unreal Engine 5, TObjectPtr is the new way for classes to hold raw pointers.
Pre UE5 you did

UPROPERTY(EditAnywhere)
UMyObject* MyObject;

Now with UE5 you should do:

UPROPERTY(EditAnywhere)
TObjectPtr<UMyObject> MyObject;

To enforce these, i highly recommend placing the following in your Target.cs file for your project (we normally just do it in the MyGameEditor.Target.cs

		if (!bBuildAllModules)
		{
			NativePointerMemberBehaviorOverride = PointerMemberBehavior.Disallow;
		}

This will enforce the use of TObjectPtr!

But there are some issues you can encounter using these. As these should ONLY be for class members, not function parameters, you may run into some issues. But fear not, Epic gave us some templates for these:

ObjectPtrDecay

Whenever const access to the underlying storage of a TObjectPtr<...> (or a container of them) we should use this. Example is here:
UPROPERTY(Transient)
TArray<TObjectPtr<AActor>> Actors;

void MyFunc()
{
    TArray<AActor*> SelectedActors = ObjectPtrDecay(Actors);
}

Another example is:

UPROPERTY(Transient)
TArray<TObjectPtr<UObject>> Objects;

void MainFunc()
{
   SomeFunc(ObjectPtrDecay(Objects);
}

void SomeFunc(TArray<UObject*> InObjects)
{
}

ObjectPtrWrap

This is the inverse of the above, basically makes a TArray<UObject*> to a TArray<TObjectPtr<UObject>>

MutableView

MutableView: safely obtain temporary mutable access to a TObjectPtr's
underlying storage.
This allows you to pass a mutable view to the TObjectPtrs to functions, etc that requires it.
void GetAllComponents(TArray<UActorComponent*>& Components)
{
  Components.Add(Blah);
}
TArray<TObjectPtr<UActorComponent>> Components;
GetAllComponents(MutableView(Components));

Hopefully this helps, just a small random bit of information!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.