Here I've briefly pointed out anything about project structure or implementation flow that I think worth mentioning.
Here the structure of the project classes has been described in a top-down approach:
- The main scene of the game ("Game" scene) contains a
MonoBehaviour
calledLevelManager
on a GameObject with the same name. this class has every other scripts that manage each part of the gameplay. - There are many
non-MonoBehaviour
classes refered as managers. the naming convention of them is likeFooManager
, which is a class that manageFoo
. the real examples areMobManager
,GateManager
,EnemyCastleManager
. Each class is in charge of managing something. - Every
MonoBehaviour
class that supposed to control a GameObject uses theBarController
convention. likeMobController
,CannonController
, ... - different behaviours of some objects, like mobs, exists in classes with
XBehaviour
naming convention. likeMovingBehaviour
andCollisionBehaviour
for mobs.
The overal structure of the code is as bellow.
-
First of all, I've used
static Action
for memory usage. Since Actions are allocation based and for each Action and it's subscribed callbacks theGarbage Collector
has to allocate some memory, using them for objects that must be instantiated a lot in the game (Like "Mobs" in this one) means allocating a lot of memory. So, Instead of defining Actions as classnon-static
members, I've defined them as static member and each object that manages toInvoke
that Action, has to pass itself as the first parameter to the callbacks. This way Instead of allocatingheap
memory for an Action on each object instance. there is only a single static one that every instance useing it. (I came out with this idea in WC so I don't really know it works or not, but it seams valid enough!:D) -
I've used
static Action
again to avoid usingSingleton
s (I'm starting to fall in love with this static Action thing). AsSingleton
s make it difficult to manage contexts, I prefer not to use them. Also, one of the most important advantages of theSingleton
classes is thair accessibility through the project. so I've used this to achieve that:- The used to be
Singleton
class containes anstatic Action
- Instances of the The used to be
Singleton
class subscribe to that Action upon initializing. - Any other class that needs to call a function from the former
Singleton
class now can invoke thestatic Action
. Instances of the formerSingleton
class has already subscribed the needed method to that Action, so it's just like calling aSingleton
object instance method. (SeeEnemyCastleManager
as an example)
- The used to be
-
For mobs creation and deletion, used Unity's built-in
ObjectPool
-
For async functions, used
UniTask
-
Realized that it's not good to use the
ObjectPool
'sGet
andRelease
function insideUniTask
casue it's not thread-safe -
I really wanted to work on the visual aspects of the project but I ran out of time.
-
As Mobs dying VFX, there is a dissolve shader on them. but it's not noticable much.