I am working with C++ for a while now and until now I have avoided this problem. But I still do not totally understand #include headers sometimes.
I created a custom LevelScriptActor. This actor needs to have a reference to one of the custom actors (A ball) in game to do something with it.
In the custom LevelScriptActor are a couple of variables I use in other classes to check whether the game is currently paused for example.
Now the ball needs to know when the game is paused. So it needs to get this information from the LevelScriptActor.
The LevelScriptActor has an #include “BSBall.h” to be able to do stuff with the ball.
The Ball needs to have an #include “BSLevelScriptActor.h” to be able to ask the levelscriptactor if the game is paused
Now this is creating errors, because the Levelscriptactor is including ball, which is including levelscriptactor again creating a Circular dependency, if I understand it correctly. But I have no clue how I can do this in the correct way…
Simple version of my code with all stuff not important deleted:
class BALLGAME_API ABSLevelScriptActor : public ALevelScriptActor
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = BSLevel)
class BALLGAME_API ABSBall : public AActor
Can someone explain me how to do this in a correct way, so I can access my levelscriptactor from my ball and my ball from my levelscriptactor without getting errors…
Forward declarations are you friend here.
Pointer and reference types don’t actually need to have seen the full definition of their type in order to be instantiated, so you can forward declare your
ABSLevelScriptActor type in
Ball.h, and then move the
Ball.cpp instead. You can likely do the same with
This works under the assumption that you don’t actually try and use that type in the header (eg, by calling a function on it) as that will require the full definition, which would only be available in your cpp files.
Maybe you should rethink your design there. The LevelScriptActor has too much responsibilities. It is setting up some level variables (checking if the game is paused and i guess some more) but it is also doing stuff with the ball. Why is it that? Does that responsibility corresponds to the LevelScript?
Although you might get away with it, I would take the responsibility of moving the ball away from the LevelScriptActor. For example, a BallController, or something like that. So now you’ll have the BallController, who knows the LevelScript and the Ball. The Ball is all alone and doesn’t know anyone. The LevelScript also doesn’t know anyone.
The BallController will be moving the ball and asking the levelscript ¿is the game paused? If so then stop movig the ball. You now got rid of the circular dependency.
Circular dependencies are pretty bad, they make your code dificult to change, it.couples everything together. It is related with a design problem. Check more info about it and how to solve them, you may also find Dependency Inversion stuff, which is applied a lot of times to solve Circular Dependencies.
Thanks for the answers! This makes it more clear to me and yes indeed I might re check my design. I did some stuff in blueprint to make a prototype fast, but I want to convert it all to code, and some stuff I copied from the way I did it in blueprint. Some things can indeed be set up better.
Anyway thanks for the quick answers I am going to check which solution works best for my game