Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

My experience with UNet so far.

Discussion in 'UNet' started by KronisLV, Dec 14, 2015.

  1. KronisLV

    KronisLV

    Joined:
    Dec 11, 2015
    Posts:
    4
    tl;dr - For someone relatively new to Unity, completely and absolutely miserable.

    <venting>
    First problem: finding how to host a master server.
    At first i thought that i'd have a look at what Unity offers. I found out that their Network services are free only for the duration of the beta phase or whatever they're calling it, so that was immediately a non-option. The alternatives weren't better - Photon's CCU basically cripples your project if you don't want to pay for it. That meant that i had to make my own implementation, which at first seemed simple enough. In theory, i could run a Unity program that would act as a master server, and make its own address public by putting it (and the port) inside of a .txt file in a Dropbox folder, which, because of having a static link, could be downloaded by the clients with the WWW class, then it could be parsed and a connection made. That's doable and simple.

    Second problem: implementing a master server.
    Managed to get the text file to update, simple enough. Then i tried to find out how the networking works. That turned out badly. The documentation for the high level networking only seems to detail the general concepts behind it, without being too concerned about giving good code examples, and seems to be geared heavily towards synchronizing the game objects, not sending general data messages. Not saying that it's not described somewhere in there, but i couldn't find it because of how much irrelevant stuff (to my problem) there was. The ordering could seriously use some work, because describing how to make game logic without explaining how to set up a server / connect to it first doesn't seem like a good idea to me.

    The search function is also crap. So i figured that i could use the lower level transport layer. That didn't work either. The documentation given for it is just a single page, which isn't too specific about what is server code and what is client code, frankly, i'm not even sure that there's a distinction of any sort (as the words host and peer are both used often, which is confusing to say the least) and in the end i couldn't get anything to work. As soon as i fixed one error, more and more seemed to pop up.

    Example: got an error telling me that the hostId should be greater than 0 and less than 0. Disregarding that this is impossible, i tried to look for documentation, which landed me here - http://docs.unity3d.com/ScriptReference/Networking.NetworkConnection-hostId.html
    In the end, i couldn't find out what is hostId or even what it is used for.

    As if it's not bad enough that i couldn't get anything functional up by myself, when i tried to look for networking information online, about a third of the pages i found through google seemed to contain information about the legacy networking, not the new one. In conclusion, unless you're prepared to spend hours of your time learning the ins and outs of how Unity does its networking, you won't get any results. Simply put, it's unintuitive, and i think i'll just go do something with jMonkeyEngine instead, despite it being technically inferior to Unity, just so i can get some actual results. At least the documentation there doesn't leave me as confused, because it's ordered in a logical way http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:networking

    Started watching a video tutorial series on youtube, but the guy making them didn't seem to be quite sure about how anything works either, nor did he describe making a server browser. Frankly, i'm starting to think that using a general C# networking library would be easier than wrapping my seemingly dense head around the concept of UNet.
    </venting>
     
  2. Erik-Juhl

    Erik-Juhl

    Unity Technologies

    Joined:
    Jul 11, 2012
    Posts:
    59
    So how about now? I'd really like to know what your initial experience was like. Feel free to private message me if you prefer.
     
  3. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    It was an interesting read, but pretty standard (check the history button to view deleted posts).

    @Stiivais - often feedback like this is good, and Unity likes to see where people are struggling because it shows where docs can be improved or workflows.
     
  4. GixG17

    GixG17

    Joined:
    Aug 18, 2013
    Posts:
    105
    What history button? I had some interest in reading his thoughts.

    I'm sure I'm not alone but sometimes I feel like I'm the only one who's struggling with UNet. UNet's been out for, what, half-a-year-to-a-year now (I forget when it was officially released) and I'm still pulling my hair out trying to implement systems that I previously had set up with the old eventually-to-be-obsolete code.

    UNet seems to make things easier for simple projects but the moment things go outside the norm, it's more of hassle than it originally was.

    Stuff like:
    • Commands can only be used by clients, RPCs can only be sent from servers.
    • Client ownership.
    • NetworkManager.
    ... has made my project really difficult to organize. My project now needs to spawn a "multiplayer" prefab that contains a script (it has all my RPCs) instead of a player GameObject because there are apparently some operations (don't remember which ones) can't be done within the NetworkManager.

    My actual player GameObject is now split into 4 prefabs (instead of one) because I need to NetworkServer.SpawnWithClientAuthority on each individual object (for body movement, head rotation, etc) and then parent them by code... which also has the side effect that the object list in the editor is only showing one player GameObject with the proper parenting PER client... all the other ones are loose in the list.

    I used to RPC procedurally generated data across my server/clients and the time it took for each client to receive that data used to be near instant. Now it takes 2-to-5 minutes to send the same kind of data and that's after I made adjustments just to make it work and I had to make these adjustments because, otherwise, I'd be bombarded by "message too long" errors (something I never experienced before).
    ... and that's, of course, not buffered because, apparently, you can't do that with UNet. which is okay I guess, it makes more sense to wait for the client to ask for the data instead of just assuming that every client wants the same data... but now I have to:
    • [Command]Cmd_AskForListCount
    • Do a while loop until ListCount > 0
    • [Command]Cmd_AskForListData
    • Do a while loop until the amount of items in the list == ListCount.
    • Done.
    Before, I used to:
    • have the server RPC ListData to clients.
    • DONE.
    In my research, I've read multiple times where people send network "messages" (similar to RPCs but would simplify a lot of the hassle, or so that's the impression I got) but I can't find documentation on it nor examples of code. This seems like a local thing only and no one talks about how to set up receivers/listeners for network play... if that's even possible.

    My project is going to be very demanding on the CPU for scripts like AI so I've previously managed a system where every client gets to control of a few of these script-heavy GameObjects and have every client delegate to a different client whenever the original client would leave the game area. I'd change client ownership. You know, to prevent the server from doing everything. I had that working before but now I have NO IDEA how to accomplish that with UNet. Hell, 4-5 months ago "SpawnWithClientAuthority" didn't even exist.

    So my impressions of UNet is that, while it all looks amazing on paper (server-to-client relationships is simpler to understand), it's a huge hassle to implement unless you're doing a basic "spawn players in level" project. Maybe all it is that the documentation is lacking but I STILL (months later) haven't recuperated from patch-day (v5.2 I think?) when I opened up my project and was bombarded by "this is deprecated code" warnings. It's devastating.

    It doesn't help that there's a lot of only-works-for-the-old-system functions still within Unity that are not labeled "Legacy"... like the SendRate in the Network menu... does that even do anything now?

    I hope my post isn't too rant-y; I've been pulling all-nighters for a while now...

    SyncVar is awesome, by the way.
     
    Last edited: Dec 14, 2015
    badawe likes this.
  5. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    That's for moderators and staff, I was replying to Unity staff there. Just being open. But yep, keeping feedback visible even if it's misguided, is a way to signal to Unity how people are generally thinking when trying to learn it. Thanks for your feedback too.
     
    GibTreaty and GixG17 like this.
  6. Velo222

    Velo222

    Joined:
    Apr 29, 2012
    Posts:
    1,437
    That sounds rough Gix. I can understand what you're saying though. Having to learn new systems is a big headache sometimes. I spent hours yesterday with Unet trying to get two units/characters in my game to damage each other properly. As I found out today, my code actually worked on a "real" internet connection, but did not work in a LAN setting. And all I was doing yesterday was testing in a LAN environment......so it never worked, which was frustrating.

    Since this is my first experience ever with networking, I'm holding out judgement until I know more of what is going on. But it has been very difficult up to this point, and I still don't understand some of the basics of the system. It's kind of making me nervous because Unet sounds like it's supposed to be "easy" in a sense. Since I'm using a host client, I think what is confusing me the most is that the host is the server -- is the host --- is the server lol. So it's hard for me to figure out what "isServer" or "isClient" or "hasAuthority" conditions need to be placed where, and most importantly, why.

    I love being able to spawn objects with client authority, as I think that makes things much easier. But I agree with GixG17 in that Unet "feels" like it's geared towards a certain style of game, and if you want to venture beyond that standard, you have to fight the system a little. Again though, these are kind of my first impressions being very new to networking, so take that as you will.

    I do, as of today, have a networked game in which you can move units around and they can shoot each other -- and I'm happy about that. Although it disconnects after awhile for some reason.....so I have more research to do! I'm glad Unity is working on a networking system though, and I hope they continue to refine it, and make it the best they can!
     
  7. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    My biggest issues is to get nice results for the network transforms' interpolation and synchronization.

    Indeed, I think that it's easier to achieve an acceptable behavior when doing a FPS-like 3D games, but some interpolation are really weird once you do something like a 2D scroller...

    By example, when the other player's finishing his jump and start walking right away, there's a lerping between the end of the jump and the lateral movement, so it's like the "player is smoothly landing" instead of having the more correct fall until the ground and then only the lateral movement.

    I've looked at a few of the examples provided, but they also contains some kind of jitters on the other player's object.

    Master server

    I did not really play with the master server, though. I understood that it's related at managing and display a nice list of ongoing games to make it easier for players to join a game instead of having to type an IP manually. I think that if I reach a point where I'll actually have to care about this topic, it would mean that my game reached a quite advanced state and I'd be thinking at the same time of the financial aspect (sell the game to pay for this other kind of services). If my goal was to make a free game, I don't think I'd put a master server at all (but I'd probably investigate if it would cost money to put it on Steam and use their "friends" system instead).

    Youth of Unet

    I think a lot of issues is also related to the youth of Unet and the fact that there's not yet any "best practices" defined yet. I expect some professional teams to have gotten quite ahead with some personal practices, but I don't expect them to start distributing their knowledge for free. So we'll have to wait a bit more before things are more stable.

    Unet also seems a system that changed the rules, so you cannot expect to use Unet the same way you were using another framework or when you were working directly with sockets or anything like that... Lucky me, I started playing around with Unity at the time of the release of Unet, so I did not have any "transition" issues... But even then, the learning curve is difficult...

    For GixG17

    What is the scenario for your need of getting data from the servel? Is it related to the procedural generation of the map? I'm also thinking about this topic from time to time, still have to find a solution, though...

    I was planning to one day investigate the lower layers of the API to send a larger set of data when a player is connecting, but it's still on my TODO list...

    But if it's another scenario, I've seen samples of code using [SyncVar] with a hook method defined (the hook method is apparently called when the value is synchronized from the server to the client). Did you already try something like that?
     
  8. GixG17

    GixG17

    Joined:
    Aug 18, 2013
    Posts:
    105
    I'm doing something a little bit more complicated than merely using a perlin noise or Random.Range to generate my map, so I can't just send a seed number across clients. The ideal scenario is to have clients ask for that data whenever they need it and, in turn give data back to the server whenever they make changes (which happens rarely) or whenever they generate their own maps.

    I used to be able to do this by using RPCs and sending the data as a string and rebuilding the data on the client. While it still technically works now now (with some adjustments), it's really, REALLY slow compared to the instant-transfer-performance I used to get. Maybe it's just a matter of increasing buffer sizes or whatnot but everything that I've done in that regard yielded no results.

    I'm reading up on Network Messages so I might find a solution there... so far all the documentation I've been reading about have been so local non-network use only.

    As for the [SyncVar] with a hook method, this is the first time I'm hearing about it. I know the basics of a SyncVar (and how to use it) but I didn't think it could (potentially) be applied to what I'm trying to do. Can you share those samples of code for me? I'd appreciate it a lot!
     
  9. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    In my case, I was thinking of a game with destructible terrain, which implies that using a seed is not possible (though a system with an original seed and a list of terrain modification could be possible).

    For the SyncVar with hook, there's not much documentation about it in the API (apart from one description line).
    I did find a very primitive sample on Reddit, though: https://www.reddit.com/r/Unity3D/co..._help_with_understanding_unet_syncvar/csi7k6h

    The "hook" is a string attribute of the SyncVar property, which contains the name of a function that will be called when the value is synchronized from the server.
     
  10. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    832
    I feel your pain (anyone starting out with uNet) it's a hard one to wrap ones head around at first.

    A massive help I found was someone else to talk to and go through my code, who has experience with uNet already. That covered most of the gotchas pretty quickly and helped me get my head around some of the core concepts, I think it helped him enforce his own understanding of how this new system works too.

    Multiplayer networks, especially realtime ones, will always be full of crazy S*** that doesn't work properly - I had to write custom SyncVar's because the standard Network Transform made my players jitter all over the place - so don't feel like you are doing something wrong or misunderstanding the way it is meant to work, it's always going to be this way and Unity have done a pretty amazing job at bringing this to us.

    Now they need to document it /me runs away!
     
    Velo222 likes this.
  11. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    @Erik Juhl
    Had new changes been made? (Docs maybe?) It sounds like something happened in between.
     
  12. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    @hawken
    Would you happen to have one of two sample of "custom SyncVar" to show us? I don't know what you really mean by that; I could probably find it after searching for a while, but getting a first quick intro-by-the-example on them could make me spare a lot of time. ;-p

    Or is it this practice I've encountered in one or two tutorials videos about using a SyncVar to store the object's position and do a manual lerping? I've to admit I did not reach efficient results with this either...

    Indeed, I also think that it's not possible to do one NetworkTransform will work with any game. Just the visual perspective through which you see the object can completely change what can be interpolated or not (by example, simple lerping is very bad when doing a 2D side scroller; finishing a jump + moving lateraly direction => smooth landing on the other players' screen).
     
  13. enhawk

    enhawk

    Joined:
    Aug 22, 2013
    Posts:
    832
    well it really depends on your need to sync data, if it's core to gameplay or cheating etc. otherwise you can do a bunch of things on the client to make things looks smoother. Thats for another thread though!
     
  14. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    Just to add on this:

    The actual usage of NetworkTransform of a game object is to obtain the most recent Transform the server has "known" about and pass it to the client, so the client will know what to do when the server's Transform and the client's Transform has a difference. It is up to the client to do client-side Transform prediction or handling to compensate the difference, and handles all the necessary logic for the player, the game, the user, or your "dummy client" to see.

    NetworkTransform is NOT, NEVER, and NEVER WILL BE used for actually making both the server and the client to have exact Transforms for a game object spawned on the network. Otherwise, Unity UNET would have very astounding client-side prediction mechanisms embedded into the engine itself.

    For example, for a game object in an RTS game, if the server's Transform marks where the host-side player wanted the game object to move towards, the NetworkTransform is used to indicate where on the client's side the host's game object is moving towards. Same goes for the client-side player.

    Or, NetworkTransform is used to mark where a game object's mesh parts are currently heading towards at on the server. Usually, this would be used in a multiplayer racing game with bots, or in games where object animations affect physics in the game.

    You can have multiple NetworkTransforms for a single game object, with each of the NetworkTransforms be used for various purposes. Such examples would be the Starting Transform and the Direction Transform, Before/After Transforms, or, if complex enough, Agent-based Simulation Transforms through other means.
     
  15. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    Sadly, I think I'll need a few more months of playing around with UNet before fully grasping the whole of your message. ;-p

    But one thing I can conclude for now (if I understood it correctly) is that, in relation to the issues I encounter (which is mostly jitters when synchronizing other players' position), I'll always need to handle the smoothing of the movements myself. Thinking about it, it's true that the interpolation mechanism will never be able to indeed always get the objects at the correct spot and will always require a bit of correction.

    Is there any kind of methods called when a NetworkTransform gets synchronized? Something where I'd be able to put such smoothing (typically lerping the transform's position to the new value)?

    Or, if I want to do such a thing, it'd be much better to use SyncVars, as I can then use a secondary set of variables to contain the server's state and lerp the transform's position little by little? Indeed, the NetworkTransform will modify the transform directly, so it's already too late to do some lerping.
     
  16. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    Just fetch the Transform from the NetworkTransform, take the values of the position, scale, rotation, etc., and use the values.

    If your game uses pathfinding, you'll need to handle pathfinding on the client side, and just use NetworkTransform to mark down where the start and the end points are.

    SyncVars can also be used, but they must be paired with [Command] and NetworkServer, (aka, only on the server-side). Also, you cannot have more than 16 SyncVars in total for 5.3.0f4.
     
  17. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    How is it possible to "just fetch the transform" from the NetworkTransform? Isn't the objective of this component to directly update the game object's transform? If this component already modified the transform to the value it received from the server, it's too late to do any lerping?

    Or is there a special mode for the NetworkTransform where it doesn't modify the transform of the game object, but which still provides you functions to retrieve the server's values?
     
  18. asperatology

    asperatology

    Joined:
    Mar 10, 2015
    Posts:
    981
    When server updates a NetworkTransform on a game object, the client will mark the game object's NetworkTransform as dirty and will try to fetch the server's NetworkTransform. Fetching the Transform is just calling on NetworkBehaviour.transform on the client to obtain the server's NetworkTransform.

    If it's too late to do any lerping, it is still up to the client to do client-side prediction. Either guess where the unit is going and correct it later on, or just instantly pan the game object to the correct position, creating a jumping effect.
     
    jathrek likes this.
  19. jathrek

    jathrek

    Joined:
    Jul 16, 2015
    Posts:
    36
    Ok, that's why I was a bit unsure about what you were talking about. I thought it was about reconciliation and lerping, instead of prediction. ;-)

    I'll leave prediction for later, as I don't even always get a satisfying enough result with the lerping to the latest server's state. ;-p

    Thanks for the tips, though, I'll try to remember them as I keep on working on my project.