One of the most important features of ECS is the separation of data and logic, and the second is data-driven logic. What is data-driven logic? Not very well understood, let's take an example A moba game, the heroes have blood bars, which are displayed on the character's head, and also on the top left avatar UI. This time the server sends a blood deduction message. How do we handle this message? In the first way, we modify the hero's blood value in the message handling function, modify the blood bar display on the avatar, and modify the blood bar on the avatar UI at the same time. This approach obviously causes coupling between modules. In the second method, the blood value is only changed in the blood deduction message processing function, and the change of blood value throws an hpchange event, and both the avatar module and the UI module subscribe to the blood value change event and handle their own logic in the subscribed method, so that each module is responsible for its own logic without coupling. ET provides a variety of events, all of which can be subscribed multiple times:
- AwakeSystem, which is thrown after the component factory creates a component, and is thrown only once, with parameters
Player player = ComponentFactory.Create<Player>();
// Subscribe to Player's Awake event
public class PlayerAwakeSystem: AwakeSystem<Player>
{
public override void Awake(Player self)
{
}
}
- StartSystem, component UpdateSystem call before throwing
// Subscribe to Player's Start event
public class PlayerStartSystem: StartSystem<Player>
{
public override void Start(Player self)
{
}
}
- UpdateSystem, component thrown every frame
// Subscribe to Player's Update event
public class PlayerUpdateSystem: UpdateSystem<Player>
{
public override void Update(Player self)
{
}
}
- DestroySystem, thrown when the component is deleted
// Subscribe to Player's Destroy event
public class PlayerDestroySystem: DestroySystem<Player>
{
public override void Destroy(Player self)
{
}
}
Player player = ComponentFactory.Create<Player>();
// The Destroy event will be fired here
player.Dispose();
- ChangeSystem, thrown when the content of the component changes, needs to be triggered manually by the developer
// Subscribe to Player's Destroy event
public class PlayerChangeSystem: ChangeSystem<Player>
{
public override void Change(Player self)
{
}
}
Player player = ComponentFactory.Create<Player>();
// need to trigger ChangeSystem manually
Game.EventSystem.Change(player);
- DeserializeSystem, thrown after component deserialization
// Subscribe to Player's Deserialize event
public class PlayerDeserializeSystem: DeserializeSystem<Player>
{
public override void Deserialize(Player self)
{
}
}
// Here player2 will trigger the Deserialize event
Player player2 = MongoHelper.FromBson<Player>(player.ToBson());
- LoadSystem, EventSystem thrown when loading dll, used for server-side hot update, reload dll to do some processing, such as re-register handler
// Subscribe to Player's Load event
public class PlayerLoadSystem: LoadSystem<Player>
{
public override void Load(Player self)
{
}
}
- normal Event, thrown by the developer himself, can take up to three parameters. Also the client hot change layer can subscribe to the mono layer Event events
int oldhp = 10;
int newhp = 5;
// Throw hp change event
Game.EventSystem.Run("HpChange", oldhp, newhp);
// UI subscribe to the hp change event
[Event("HpChange")]
public class HpChange_ShowUI: AEvent<int, int>
{
public override void Run(int a, int b)
{
throw new NotImplementedException();
}
}
// The model header blood bar module also subscribes to the hp change event
[Event("HpChange")
public class HpChange_ModelHeadChange: AEvent<int, int>
{
public override void Run(int a, int b)
{
throw new NotImplementedException();
}
}
- There are many other events, such as message events. Message events are declared using MessageHandler and can take parameters to specify which server to subscribe to.
[MessageHandler(AppType.Gate)]
public class C2G_LoginGateHandler : AMRpcHandler<C2G_LoginGate, G2C_LoginGate>
{
protected override void Run(Session session, C2G_LoginGate message, Action<G2C_LoginGate> reply)
{
G2C_LoginGate response = new G2C_LoginGate();
reply(reply);
}
}
More specific message events will be explained in detail when we talk about messages
10. numeric events, numeric module and then explain
...... , more events to be developed by yourself.
The logic of the ET framework is driven by the various events above.