Book/5.5Actor Location-EN.md
Actor model only needs to know each other's InstanceId to send messages, which is very convenient, but sometimes we may not know each other's InstanceId, or an Actor's InstanceId will change. ET provides a mechanism to send messages to such objects, called Actor Location The mechanism is called Actor Location. The principle is relatively simple.
Note that the Actor model is purely a server-side message communication mechanism, which has nothing to do with the client. We can use the server-side actor model for forwarding, so some client-side messages also inherit the actor interface. What happens if we don't use the actor interface on the client side? For example, the message Frame_ClickMap
message Frame_ClickMap // IActorLocationMessage
{
int64 ActorId = 93;
int64 Id = 94;
float X = 1;
float Y = 2;
float Z = 3;
}
We may not need the field ActorId, the message is sent to Gate, gate sees that it is a Frame_ClickMap message, it needs to be forwarded to the Unit on the Map, forwarding is still good, gate can get the location of the unit corresponding to the map from the session, and then forward it, the problem comes, Frame_ ClickMap message to the map, how does the map know which object the message needs to be given to? There are several designs at this point.
ActorLocation messages are sent
// Get the ActorLocationSenderComponent from Game.Scene, then get the ActorLocationSender via Entity.Id
ActorLocationSender actorLocationSender = Game.Scene.GetComponent<ActorLocationSenderComponent>().Get(unitId);
// Send the message through the ActorLocationSender
actorLocationSender.Send(actorLocationMessage);
// send the Rpc message
IResponse response = await actorLocationSender.Call(actorLocationRequest);
ActorLocation message processing is almost the same as Actor messages, the difference is that the two abstract classes inherited are different, note that the abstract class of actorlocation has an additional Location
// The first generic parameter of the abstract class is the type of the Actor, and the second parameter is the type of the message.
[ActorMessageHandler(AppType.Map)]
public class Frame_ClickMapHandler : AMActorLocationHandler<Unit, Frame_ClickMap>
{
protected override ETTask Run(Unit unit, Frame_ClickMap message)
{
Vector3 target = new Vector3(message.X, message.Y, message.Z);
unit.GetComponent<UnitPathComponent>().MoveTo(target).Coroutine();
}
}
// To handle Rpc messages, you need to inherit the AMActorRpcHandler abstract class. The first generic parameter of the abstract class is the type of the Actor, the second parameter is the type of the message, and the third parameter is the type of the returned message
[ActorMessageHandler(AppType.Map)]
public class C2M_TestActorRequestHandler : AMActorLocationRpcHandler<Unit, C2M_TestActorRequest, M2C_TestActorResponse>
{
protected override async ETTask Run(Unit unit, C2M_TestActorRequest message, Action<M2C_TestActorResponse> reply)
{
reply(new M2C_TestActorResponse(){Info = "actor rpc response"});
await ETTask.CompletedTask;
}
}
There are many cities (processes) in China, and many people (entity objects) living in the cities, each with an ID number (Entity.Id). A person needs to apply for a residence permit in each city and is assigned a unique residence permit number (InstanceId). The format of the residence permit number is 2 bytes city number + 4 bytes time + 2 bytes increment. The ID number never changes, but the residence permit number changes every time you go to a city. Now there is a China Post (actor). Suppose Xiaoming wants to send a letter to his girlfriend Xiaohong