Hi.
Im working on a networked inventory system and some other stuff for which Im relying on interfaces. I have a few classes implementing those interfaces and I need to send them to the client via RPC but keeping the type. Right now Im just using a descriptor USTRUCT to just send a simplified representation but I would like to also have the ability to use polymorphism.
In short, is there a way to serialize a class and send it by rpc call and deserialize it so it keeps the type information?
You are over-complicating things.
You don’t have, neither should, to send a whole object over network. Networked classes can implement OnRep notify functions for replicated UProperties, wherein you can manually trigger interface calls for Clients or Server, passing in a reference to the object executing that interface call… As soon the property changes, within your OnRep method you can update the local references for anything that needs it, without ever convoluted transfer the whole object through network data transfer which is abysmal thing to do on a game.
You can replicate any UObject inherited classes, actors and components are supported by default. You can’t really just send them with an RPC, you have to construct them on the server, then serialize them with the ReplicateSubjects function and they will be constructed on the client. Once they have been replicated you can reference them in RPC’s or as replicated variables over the network. Here is a helpful Wiki article on that: A new, community-hosted Unreal Engine Wiki - Announcements and Releases - Unreal Engine Forums
So it depends on what your inventory system needs to do. If you have an FPS style game with few weapons then you might want to use replicated actors, if you have a lot of items like in ARK you probably rather want to use custom object classes.
Thanks for your answers guys. I think I didnt explain it very well. I’m aware that any uobject can be replicated but I only want to replicate them when needed. There is no need to update the status of an object constantly in the client if the player will only see it when he opens the inventory. I though about it being overcomplicated but keep in mind that the serialization would include only a few properties. Right now my ustruct is only composed by 4 bytes.
Maybe the overhead of replicating a subset of uobject to their owning connections only is not that big. In that case I would take that approach.
Ok I see. If you really only need to know about your items when your inventory is open you could do a workaround with custom serialization to avoid objects being replicated constantly, but I don’t know if that would actually be that beneficial in terms of networking versus replicated objects, besides not being very flexible and more complicated. So replicating your items as lightweight objects only to the owning client would be the nicest solution in my opinion.
Thanks! Ive been thinking around this the last two days and that just clears it out. I will replicate uobjects as properties of my inventory actor and change ownership as needed, also low net relevancy should help.
@Fluppi393
You said I could serialize a UObject, send it and then deserialize it in the client. I can’t find any documentation regarding that. The only thing I could find while looking the reference was the UObject::Serialize function which gives me a FArchive but I have no idea how that structure is composed.
Have a look at this specific section of the article:
The serialization is done in the UActorChannel::ReplicateSubobject function. It is deserialized automatically on the client.
So in your example you would probably want to store all your items in a replicated array, then in your actors ReplicateSubobjects function iterate through all items and replicate them. Then they will appear in the array on the client.
Thanks! I will take a look. I will need to change object’s outer dynamically and also find a way to forward the uobjects to the first uobject in the hierarchy but I think it should be posible.