Reading Ellan Jiang's Unity GameFramework: The Entry
Ellan Jiang’s Unity GameFramework is a popular (1400+ stars on GitHub on September 2019) and elegant framework for Unity game programmer. I want to walk through the codebase and take some notes on it. I think this is a good way to learn it.
There are many modules supported by the GameFramework, including DownloadManager
, EntityManager
, EventManager
, and FsmManager
etc. Each class of these modules has to implement an abstract class GameFrameworkModule
, which looks like
internal abstract class GameFrameworkModule
{
internal virtual int Priority
{
get
{
return 0;
}
}
internal abstract void Update(float elapseSeconds, float realElapseSeconds);
internal abstract void Shutdown();
}
The Update
method is like the MonoBehaviour.Update
method, that is used to update some states of objects. For that the framework works correctly, you (the user) have to call, in a specific place, the Update
method of every module. The GameFramework also provides a static class GameFrameworkEntry
which lets you can easily do this job.
For example, you can create a script called Entry
, which shouldn’t be destroyed after the game is launched. In Entry.Update
, you can write the below statement to update every module.
GameFrameworkEntry.Update(Time.deltaTime, Time.deltaTime);
Here is the implementation of it:
public static void Update(float elapseSeconds, float realElapseSeconds)
{
foreach (GameFrameworkModule module in s_GameFrameworkModules)
{
module.Update(elapseSeconds, realElapseSeconds);
}
}
The Shutdown
method expects to be invoked when the game shuts down. Similarly, GameFrameworkEntry
provides a method to shut down all modules:
public static void Shutdown()
{
for (LinkedListNode<GameFrameworkModule> current = s_GameFrameworkModules.Last; current != null; current = current.Previous)
{
current.Value.Shutdown();
}
s_GameFrameworkModules.Clear();
ReferencePool.ClearAll();
GameFrameworkLog.SetLogHelper(null);
}
The Priority
method is used for deciding the priority of updating of each module. s_GameFrameworkModules
is a linked list to hold all game modules. The Priority
larger, the position of the relative game module at s_GameFrameworkModules
is fronter.
How to get each module? You just need to call GameFrameworkEntry.GetModule<T>()
; If the game module you request is not existed, it will create one.
private static GameFrameworkModule CreateModule(Type moduleType)
{
GameFrameworkModule module = (GameFrameworkModule)Activator.CreateInstance(moduleType);
if (module == null)
{
throw new GameFrameworkException(Utility.Text.Format("Can not create module '{0}'.", moduleType.FullName));
}
LinkedListNode<GameFrameworkModule> current = s_GameFrameworkModules.First;
while (current != null)
{
if (module.Priority > current.Value.Priority)
{
break;
}
current = current.Next;
}
if (current != null)
{
s_GameFrameworkModules.AddBefore(current, module);
}
else
{
s_GameFrameworkModules.AddLast(module);
}
return module;
}