Download

How can I avoid a circular dependency with TWeakObjectPtr?

This is a follow up post from High build times for the shooter game example - C++ Gameplay Programming - Unreal Engine Forums

I discovered that UE4 is doing unity builds by default and it keeps all .h together. That means if one .h changes every .h file needs to be reparsed and the .cpp files need to be recompiled.

The unity build time is too much for me so I decided to manage the includes by myself.


ShooterCharacter.h
---
The problem:
#include "ShooterTypes.h"
#include "ShooterCharacter.generated.h
UCLASS(Abstract)
class AShooterCharacter : public ACharacter
{
....
/** Replicate where this pawn was last hit and damaged */
	UPROPERTY(Transient, ReplicatedUsing=OnRep_LastTakeHitInfo)
	struct FTakeHitInfo LastTakeHitInfo;
....
};
ShooterTypes.h
--

class AShooterCharacter;
USTRUCT()
struct FTakeHitInfo
{
....

	/** Who hit us */
	UPROPERTY()
	TWeakObjectPtr<class AShooterCharacter> PawnInstigator;

....
};

But I have a problem with this line in the TWeakObjectPtr class.


static_assert(CanConvertPointerFromTo<T, UObject>::Result, "TWeakObjectPtr can only be constructed with UObject types");

Because I forwarded AShooterCharacter it doesn’t seem to know yet that it is a UObject and therefore doesn’t compile. How can I avoid this problem?

At the moment I think the only way I can make it compile is to define FTakeHitInfo in ShooterCharacter.h.

If it’s doing a static assert, you’ll need to include “ShooterCharacter.h” in your “ShooterTypes.h” rather than just a simple forward declaration.

EDIT: BAH, I see your problem. Yea, you can move that class to ShooterCharacter.h after you defined AShooterCharacter.

I don’t see how moving it into the same header should make any difference. That said, I can’t recreate this problem. As far as I can see, TWeakObjectPtr appears to work fine with forward declared classes.

That is probably because you are using unity build and/or the default ShooterGame include “ShooterGameClasses.h”.

Btw I fixed it by pulling it into the same file.

I’m facing this exact issue now. Have you found a solution yet?

In almost an exact duplicate of your issue:

  • I use a CustomCharacter that includes CustomWeapon and Type.H
  • I use a Types.H that uses custom character
  • I use CustomWeapon that includes CustomWeapon and Type.H

I can never solve this.

In the types.h , when attempting to instantiate the Structure that uses CUstomCharacter ( in that lasttakehitinfo ) , i get that same error.
I tried forward declaring CustomCharacter.h in Types.h’s header , i get that assert error

It’s not with twekaobjectptr specifically, it’s just as you said a circular dependency. It’s not just forward declaration that matters, the order of declaration also matters.This may help.