An interface that should be used to declare a Rpc struct.
RPCs are "one-shot" messages that can be sent and received by both the client and server, and can be used for different
purposes. E.g. Implementing a lobby, loading level logic, requesting to spawn a player etc.
Unlike ghost SnapshotData, rpc messages are sent using a dedicated reliable channel and
are therefore guaranteed to be received.
As they're reliable messages, RPCs are not meant to be used as a replacement for ghosts, nor for sending data that will change frequently,
nor player commands (ICommandData and IInputComponentData). Why not?
1) There is a maximum number of reliable packets that can be in-flight at any given time.
2) Latency is introduced by the ordering guarantee of the reliability pipeline.
An RPC struct can contain any number of burst-compatible fields. However, once serialized, its size must fit into a single packet.
Large messages are not supported (NetworkParameterConstants.MaxMessageSize and account for header sizes).
It is possible to partially mitigate this limitation by creating a custom INetworkStreamDriverConstructor and
setting a larger MaxMessageSize (but that will only work in favourable conditions and networks (ensure thorough testing!)) or by
adding a FragmentationPipelineStage stage into the reliable pipeline (channel).
Usage: To send an RPC declared using the IRpcCommand interface, you should create a new entity with your rpc message component,
as well as a SendRpcCommandRequest (which will notify the NetCode system that it exists, and send it).
It is best to do this with an archetype to avoid runtime structural changes:
m_RpcArchetype = EntityManager.CreateArchetype(..);
var ent = EntityManager.CreateEntity(m_RpcArchetype);
EntityManager.SetComponentData(new MyRpc );
RPCs declared using the IRpcCommand will have serialization and other boilerplate code for handling
the SendRpcCommandRequest request automatically generated.
For example:
Because the serialization is generated by our source generator, only types recognized by the code-generation system
(and that are available to use inside commands and rpcs) are going to be serialized.
See TypeRegistryEntry for other details.
The OutgoingRpcDataStreamBuffer is processed at the end of the simulation frame by the
RpcSystem, and all messages in queue attempt to be sent over the network (assuming the reliable
buffer is not full, as mentioned).
To distinguish between a "broadcast" RPC and an "RPC sent to a specific client", see SendRpcCommandRequest.
RPCs do not make any guarantees regarding arrival relative to ghost snapshots.
E.g. If you send an RPC first, and then send a snapshot, you must assume that they'll be received in any order.
However, all RPC network messages are received in the exact same order that they are "sent" (NOT "raised"!).
Did you find this page useful? Please give it a rating:
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.