NetworkVariables and RPC calls are unable to serialize Interfaces
See original GitHub issueIt seems that network variables and RPC methods don’t work with Interfaces.
Network Variables: the following will not work, we will get a complaint about a missing parameterless constructor, even though we have one in the implementing classes.
private NetworkVariable<IOrder> _currentOrder;
public IOrder CurrentOrder
{
get => _currentOrder.Value;
private set => _currentOrder.Value = value;
}
The Interface IOrder inherits from INetworkSerializable and is implemented by the base class Order, and the latter is used as the base class for other “order like” classes. So I don’t actually use the implementing class “Order” directly, I use its implementing classes that inherit from it.
I did notice that the network variable _currentOrder starts out NOT null, as in I never called _currentOrder = new NetworkVariable<IOrder>(), but it’s as if Unity does that on its own during initialization, and then tries to serialize it, but probably doesn’t know what implementation to use (since I didn’t assign anything to it yet) and I’m guessing that causes the “missing parameterless constructor” error. I messed around a bit by overriding the NetworkStart method, and explicitly setting my network variable to null “_currentOrder = null”, and then later assigning it to a new NetworkVariable object when I’m ready to use it, and that seemed to have fixed that error I was getting, but It seemed too hacky of a solution and probably not what I should be doing; also not sure if that will cause any side effects.
If we replace the interface IOrder with its implementing class, it will now work.
private NetworkVariable<Order> _currentOrder;
public IOrder CurrentOrder
{
get => _currentOrder.Value;
private set => _currentOrder.Value = (Order)value;
}
RPC methods: I was unable to find a workaround, it seems like we cannot pass an Interface as a parameter and have to pass the implementing class instead. the following will not work, our “IOrder order” parameter will be null, it will not serialize, but if instead we use the implementing class “Order”, it will work. This is kinda limiting, I’d rather pass an interface and not an implementing class (as I have many).
[ServerRpc(RequireOwnership = false)]
public async void IssueOrderServerRpc(IOrder order, ServerRpcParams serverRpcParams = default)
Is this a bug/limitation or am I doing something wrong?
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (4 by maintainers)
Top GitHub Comments
This is not final. I was just explaining how serialization in MLAPI currently works. If you need to send different types with the same parameter you could write a custom INetworkSerializable which first serializes a number indicating the type and then reconstructs an object of a specific type.
NetworkVariables and RPCs are strongly typed. They don’t just support no interfaces, they also don’t support base classes or
object
etc.The reason for that is because when MLAPI serializes your object it does not include any type information. So the other side would’t be able to reconstruct the type and deserialize it again.