question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

NetworkVariables and RPC calls are unable to serialize Interfaces

See original GitHub issue

It 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:open
  • Created 2 years ago
  • Comments:7 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
LukeStampflicommented, May 3, 2021

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.

1reaction
LukeStampflicommented, May 3, 2021

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to implement RPC's with interface parameters.
I'm trying to send messages between server and client where the RPC parameter is an interface, allowing for the sending of different ...
Read more >
sending an RPC with class instance give an error - unity ...
I guess you could first off try to do what the error says: "Implement INetworkSerializable". To Implement that Interface you would write: ....
Read more >
Custom Serialization can't be used because of compile ...
custom serialization handlers feature is not ripped out from the codebase (works for NetworkVariables) but we didn't roll them over to RPCs yet....
Read more >
INetworkSerializable
Types implementing INetworkSerializable are supported by NetworkSerializer , RPC s and NetworkVariable s.
Read more >
RPC vs NetworkVariable
NetworkVariables are eventually consistent. This means not all value changes will be synced, contrary to RPCs, where 5 calls to an RPC will ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found