Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. We've updated our Terms of Service. Please read our blog post from Unity CTO and Co-Founder Joachim Ante here
    Dismiss Notice
  4. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

Unity Multiplayer Mirror - Networking for Unity (UNET Replacement)

Discussion in 'Connected Games' started by vis2k, Aug 11, 2016.

  1. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Final 2018 Update and post #1000 on this thread!
    2018 is coming to an end, and it's been one hell of a year for Mirror. It's shaping up really well.
    • We got rid of a LOT of HLAPI magic
    • We started diving into the Weaver, untangling it into several subclasses and simplifying where possible.
    What this means for you guys: Mirror is now faster and more stable than ever before. 500 CCU in a real world project like uMMORPG should be no problem at this point. 1000 CCU are getting more realistic every day, hopefully we can test this in late 2019.

    What this means for us: we are now very comfortable with all aspects of Mirror, including the Weaver. Code was simplified to the point where we can act fast if we need to fix bugs or add new features. And most importantly, we trust it with our multiplayer games.

    ----------------------------------------------------
    Big thanks to all the people that recommended Mirror to their friends, reported bugs, helped people out in our Discord, spread the word and trusted us enough to use it in their game projects.
    Special thanks to all the developers in our discord, especially @goldbug who's in the trenches with me even today, when everyone else is partying.

    We wish you all a great start into 2019!
    ----------------------------------------------------

    We have one last update for 2018:
    NetworkSettings.sendInterval
    and GetNetworkSendInterval were replaced with NetworkBehaviour.syncInterval. Removes about 100LOC, including lots of weaver magic. Easier to deal with now too, no more custom [Range]sendInterval settings for components that should have variable intervals.



    ---
     
    MarkusGod, Hitch42, Dareheim and 3 others like this.
  2. Dareheim

    Dareheim

    Joined:
    Oct 12, 2013
    Posts:
    4
    Happy New Year, devils:D
     
  3. bran76765

    bran76765

    Joined:
    Jul 14, 2018
    Posts:
    3
    Hey, I have a problem that I just can't seem to figure out (and maybe someone here can help me).

    So I'm trying to call a function from a client to get executed on the server. Seems easy enough. I try the [Command] attribute and the host works but a single client doesn't. I try the [ClientRpc] Attribute and get the error "Rpc function being called on client." I've tried other stuff too but nothing seems to be working to get the client syncing its actions and functions with the server.

    Code (CSharp):
    1. void Update()
    2.         {
    3.             float time = Time.deltaTime;
    4.             CmdUpdateSettings();
    5.         }
    6. [Command]
    7.         public virtual void CmdUpdateSettings()
    8.         {
    9.            //Do Stuff here
    10.         }
    11.  
    [Command] only works on Host and the client just straight out skips the [Command] but when I try to do a [ClientRpc] it throws an error as well. Any ideas?

    Edit: Also tried the server in the unity editor and I get the error "Command function called on server". So looking like even though I'm using them for their intended purpose, I'm getting errors because of it lol
     
  4. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    @bran76765
    1. You are calling the [Command] on every frame. That is nuts, that is a lot of traffic on your network. You should only call the command on key presses, or button presses or something like that.
    2. Is this [Command] on a player object? You need to get familiar with the authority model of Mirror. If you have 3 clients connected to your server, then there will be 4 instances of your this player object one in each client and one in the server. One of the clients will be designated as the owner of that object, and only he is allowed to call [Command], the other ones will get errors. So check if isLocalPlayer before calling the [Command]
    3. Make sure the player object is assigned as the player prefab in the network manager and auto spawned (at least to start with)
    4. [Commands] can only be called in the client (or host), and they get executed in the server (or host).
    5. You might want to watch some Unet tutorial to get familiar with the framework
     
  5. bran76765

    bran76765

    Joined:
    Jul 14, 2018
    Posts:
    3

    1. Yes I'll try to slim it down after but atm I just need it working.
    2. Yes it's on a player object and I've tried checking if isLocalPlayer but it still gets passed through all the same and skips all the commands.
    3. It's not the player prefab, I'm using uMMO's systems and both host and client are getting spawned the same way....but I'll try taking another look at the client and see how it gets spawned in.
     
  6. jacknero

    jacknero

    Joined:
    Aug 15, 2018
    Posts:
    5
    Happy New Year Guys.
    I recently meet some message transport problems.
    I send a spawnRequest from Cient to Host like this:
    Code (CSharp):
    1. myClient.Send(NetworkMessages.SpawnRequestMsg, new StringMessage(SteamUser.GetSteamID().m_SteamID.ToString()));
    On the Host I got a "EndOfStreamException: Unable to read beyond the end of the stream. " error.
    I checked the message I send by a modified TransportSend method
    Code (CSharp):
    1. SteamNetworking.SendP2PPacket(steamId, bytes, (uint)numBytes, eP2PSendType, channelId)
    and found that message 21 Bytes long,consists of a sring of SteamID(17) after a 4 Bytes unknown data.
    I call it Unkown because the msgType should normal a short ,it should be only 2 Bytes long.
    Does this caused the "ReadByte"error?
     
  7. jacknero

    jacknero

    Joined:
    Aug 15, 2018
    Posts:
    5
    After I checked the data the Host recieved ,I found it actually recieved nothing .
    And the send method also return a fail result.
    It seems it's the steam things problem ,not mirror's for now.
     
  8. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    Channels were restored a while back. they work for [Command],[ClientRpc],[TargetRpc] and [EventRpc] and custom messages, But they do not work for syncvars and synclists since unreliable does not make sense for them.

    One of our discord users already made a steam transport for Mirror.
    https://github.com/FizzCube/SteamNetNetworkTransport
    and it does support channels.

    I suggest you take a look at that


    If you use steam, you are using UDP, our TCP transport would be completely unused and you don't need to worrry about it.

    That error normally means that your messages are corrupted for some reason. Either your transport is doing something wrong with the message, or your components override OnSerialize/OnDeserialize and they are not handling the data correctly.


    By all mean, join us in discord where most of the action happens.
     
  9. VrTechEx

    VrTechEx

    Joined:
    Aug 4, 2013
    Posts:
    23
    I get the error when I change to .net 4.x

    Code (CSharp):
    1. Unable to delete file Library/ScriptAssemblies/Assembly-CSharp.pdb: Sharing violation on path Library/ScriptAssemblies/Assembly-CSharp.pdb
    2. UnityEngine.Debug:LogWarning(Object)
    3. Mirror.Weaver.Weaver:Weave(String, IEnumerable`1, IAssemblyResolver, String, String, String)
    4. Mirror.Weaver.Weaver:WeaveAssemblies(IEnumerable`1, IEnumerable`1, IAssemblyResolver, String, String, String)
    5. Mirror.Weaver.Program:Process(String, String, String, String[], String[], IAssemblyResolver, Action`1, Action`1)
    6. Mirror.Weaver.<>c:<.cctor>b__0_0(String, CompilerMessage[])
    7. UnityEditor.Scripting.ScriptCompilation.EditorCompilationInterface:TickCompilationPipeline(EditorScriptCompilationOptions, BuildTargetGroup, BuildTarget)
    8.  
    Any ideas?
     
  10. socialsumate

    socialsumate

    Joined:
    Apr 29, 2018
    Posts:
    11
    Is it possible to create a lobby using mirror?
     
  11. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    @VrTechEx This is caused by the incremental compiler in 2018.3. The pdb is not essential so we just print a warning. You can ignore this warning.

    On a side note, if you are using unity 2018.3, make sure to get the 2018 branch. The version from the asset store (master branch) has known issues with it.
     
    VrTechEx likes this.
  12. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Yes. I did this in my uMOBA asset - which is the only Mirror lobby example as far as I know.
    There is also 'network lobby' asset on asset store, but it still uses UNET and it's full of bugs.
     
  13. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    News: new NetworkTransform is live. It only syncs the transform, and it actually uses interpolation now.

    NetworkRigidbody etc. may follow, but using NetworkTransform for everything should do just fine - because in the end, it's always just about the position and the rotation. If you use Rigidbodies then consider setting to kinematic on everything that doesn't have authority.

    This removes almost 2000 lines of magic code from Mirror, which is huge.

    Lines of Code overview:
    • UNET: 21129 lines of code
    • Mirror: 11134 lines of code (7681 without Weaver)
    That's half as much code that your CPU needs to worry about.
    That's half as much code that we need to worry about when debugging and adding features.
    That's half as many possible bugs (not to mention all the broken code that we rewrote)
     
    validname1, JimChan88 and pesapower like this.
  14. pesapower

    pesapower

    Joined:
    Oct 13, 2015
    Posts:
    1
    That's really good news, thank you really much for your fabulous work!
     
  15. Paradoks

    Paradoks

    Joined:
    Oct 13, 2009
    Posts:
    415
    Will mirror work with webGL(client) / linux(server) games ?
     
  16. AnthonE

    AnthonE

    Joined:
    Sep 30, 2015
    Posts:
    2
    This was some amazing timing. I've been using UNet from release and saw this project along the way. I figured I would hold out for as long as I could. So last night, I gave up trying to get my transforms to sync better. I came here to check the latest about the project. This post had perfect timing for me!

    Then after reading about all the bugs that Mirror fixes, I realized just how buggy my game was thanks to Unet. No way I would ever reach 100 players on one server. Pretty sure I was getting out of sync with just 7-8 players, explaining the never before seen bugs.

    Thanks to everyone who has helped to contribute to this whole project! This has really reinvigorated the work on doing right now. After Unet support was dropped I was really disappointed. You all saved the day.
     
    vis2k likes this.
  17. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    Shiny new feature: The 2018 branch now has a really fast and modern async websocket transport. It can also listen to multiple transports at the same time! Your facebook users (websockets) and android users (tcp or whatever transport you want) can connect to the same server and interact with each other.



    This is the default setup, both TCP and Websockets are on, listening on different ports. Out of the box, your project will run fine if you build it as standalone or webgl.
     
  18. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Yes

    Thanks mate, we are glad that you like it!
     
  19. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,200
    Nice, can one be added for UDP support, so TCP and UDP maybe with Websocket aswel?
     
  20. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    It is doable, but the only UDP based transport we have built in is LLAPI. We can't turn LLAPI on by default because it kills FPS.

    You can easily do this yourself. Something along these lines:


    Code (CSharp):
    1. public override void InitTransport()
    2. {
    3.     TransportLayer tcpTransport = new TcpTransport();
    4.     // configure port and whatnot
    5.  
    6.     TransportLayer ignoranceTransport = new IgnoranceTransport();
    7.     // configure port and whatnot
    8.  
    9.     TransportLayer websocketTransport = new WebsocketTransport();
    10.     // configure your websocket transport
    11.  
    12.     // create a transport that multiplexes between all 3
    13.     NetworkManager.transport = new MultiplexTransport(tcpTransport, ignoranceTransport, websocketTransport);
    14. }
     
  21. Roamer79

    Roamer79

    Joined:
    Oct 25, 2016
    Posts:
    31

    Whoooo!!! I've been waiting for this to be fixed!! Good job.

    Sorry to be greedy by any chance we can incorporate networkchild objects into this or fix the NetworkTransformChild as well?? Would be nice just to have it all in one component!

    Good job and thank-you!!
     
  22. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Already did. Still called NetworkTransformChild.
     
  23. Roamer79

    Roamer79

    Joined:
    Oct 25, 2016
    Posts:
    31
    Awesome! Double thanks!!! Hey the interpolation user setting are gone! Is it all optimized?
     
  24. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Which settings to do you mean? It didn't have interpolation before.
     
  25. Happycamper8

    Happycamper8

    Joined:
    Aug 31, 2017
    Posts:
    7
    A new problem for me! May be just the localhost problem, not sure.

    I've got things working again with Mirror, and the multiplayer training simulation is working great. I created it as a proof of concept so I added only 4 "players" connecting to the "game". Things have been working great, however in the end I need a total of 12 connected.

    Just got the thing setup so I could add 12 total "players". When testing it out I get the following:

    I launch the Host using unity.
    I launch 4 instances of the program by double clicking the exe. These four connect in using localhost.
    I now try a 5th instance making 6 total players and the message showing up in the unity console is the following:
    Server too full, disconnected a client

    It seems to only allow connecting in a total of 5 players. When adding the 6th, that message shows up.

    Is this due to using localhost? Will this error happen if I use 12 different computers and not localhost? I may be screwed if I can't use more than 5 total players. Also, I may be stating terms incorrectly such as localhost as I'm not really a programmer. Talk to me like I'm stupid :)

    Thanks
     
  26. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,200

    "We can't turn LLAPI on by default because it kills FPS." ...why does it kill fps? Would be great to see a working example of this with TCP and UDP support. Personally think uSurvival should be split up to use UDP for the movement/shooting while TCP for chat/inventory...? will it happen?
     
  27. Happycamper8

    Happycamper8

    Joined:
    Aug 31, 2017
    Posts:
    7
    I apologize everybody. Just noticed there is a max connections setting and it was set to 4 by default...
    Thanks
     
  28. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    Ideally I agree with you: movement via UDP/unreliable, chat, inventory, etc via TCP/reliable.
    That is not done yet, and that is different from what I posted before.

    LLAPI is a black box, there is no telling why it does anything. What I can tell you, is that a lot of people experienced higher FPS when we switched from LLAPI to Telepathy. It looks like LLAPI sleeps on every frame or something, who knows.

    LLAPI is on it's way out, I believe they removed it on 2019.1 already, so it is probably not smart to rely on it for your game. There is another transport available with UDP: Ignorance, which is based on ENET. The problem is that this is a native library written in C, so it is not portable to all platforms.

    Personally, I think the way to go is to have a small, simple unreliable only UDP transport with System.Net classes. Have the unreliable channel use that transport and the reliable channel use TCP. Someone has to do that work. If you care about unreliable, and you have the skills, you are welcome to write such transport. HMU in discord if you have questions or want to brainstorm about it.
     
  29. Player7

    Player7

    Joined:
    Oct 21, 2015
    Posts:
    1,200
    Yeah I wouldn't want to use LLAPI it is as you say a black box, and worst just awful for headless terminal servers as the black box nature of compiled source code means you can't change shhhit about it.. like it spitting out errors in the console output.. :mad: sucks if you wanted to have a console based gui.. I know I tried.. and gave up when they wouldn't be able to do anything about that issue..because of multiple platforms doing things differently.. still there are a bunch of other open sourced UDP based frameworks that could be supported.. like https://github.com/RevenantX/LiteNetLib ?

    It's not me, really not in my skillset at all, I just want something that is already proven to work with some examples I can build on from done in this way really...

    "HMU in discord if you have questions or want to brainstorm about it."

    might do just to see where things are going with it and updates in this area.
     
  30. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    I will be happy to answer questions and offer guidance if someone wanted to take on this project.

    LiteNetLib is essentially an RUDP transport, that supports unreliable. Just like Ignorance and LLAPI. If we don't need reliable (because we have TCP for that), then it is overkill and we would be using maybe 10% of their code. A class that just sends and receives udp packages would be a lot simpler.
     
    Last edited: Jan 11, 2019
  31. Roamer79

    Roamer79

    Joined:
    Oct 25, 2016
    Posts:
    31
    Well its been ages since I last looked at Network Transform but last time I did (before mirror) it used to look like this: (having threshold and interpolation variables)

     
  32. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    There is an interpolate movement factor, yes. But it did not interpolate transform movement before. It does now :)
     
  33. Roamer79

    Roamer79

    Joined:
    Oct 25, 2016
    Posts:
    31
    Maybe something is missing in my update but when I add Network Transform now all I get is below. I have no interpolation controls or thresholds just a compress rotation box?? What have I done?!!!!
    upload_2019-1-13_10-4-55.png
     
  34. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    You did nothing wrong, that's just the new NetworkTransform. Takes care of everything internally for you.
     
    hopeful likes this.
  35. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    Great news everyone. Mirror is now moving to a source based asset. No more compiling mirror with visual studio or importing mirror DLL’s, no more messing with editor/standalone dlls. Instead, you import mirror sources in your project and it just works.

    This is already released in https://github.com/vis2k/Mirror/releases/tag/master-1094 Just download Mirror.zip and decompress in your Asset folder.

    Note, for those of you upgrading from previous versions of Mirror, you will need to replace your NetworkIdentities, NetworkProximityCheckers and any other mirror component you might be using.
     
    vis2k and hopeful like this.
  36. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Easiest way to upgrade:
    1. drag all networked prefabs into the scene
    2. select them all
    3. in Inspector debug mode: drag in the new NetworkIdentity/NetworkProximityChecker scripts into the components that are now missing them.
    4. Apply each prefab and delete from scene again.

    Shouldn't take longer than a minute or two.
     
  37. Roamer79

    Roamer79

    Joined:
    Oct 25, 2016
    Posts:
    31
    Cool that's great and thanks for clarifying. Will test this week!
     
  38. Serinx

    Serinx

    Joined:
    Mar 31, 2014
    Posts:
    479
    Does Mirror allow you to save persistent data to a database?
    Would I need to get uSurvival or something for an example of that?

    Thanks
     
  39. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    It allows it in the sense of that it does not get in the way :p. Mirror is a networking library for getting your server and client to talk to each other. Databases are out of scope. You can use any database you want in your server, and just use mirror to communicate with the clients.
     
  40. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    40
    Lots of really cool changes for 2019! Thanks guys!
     
  41. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    Mirror (master) now works in unity 2018.3+. You no longer need the 2018 branch.
    If you are using 2018 branch, you can keep using it, it is not going anywhere.
    Hopefully we can merge some of the stuff in there to master.
     
  42. kingbaggot

    kingbaggot

    Joined:
    Jun 6, 2013
    Posts:
    15
    Hi - I'm using the Pong example to try learn how this works - running between two PCs on a Lan. It's working, which is great buuut.

    I'm trying to send a message from the client to the server (in the script on the player when a key is pressed) and I've read up on UNet how it's achieved there but I'm foxed.

    this is what I've got in the player script. The client.Send part is where it's erroring as it's not defined - but It doesn't seem to be defined in any of the examples I've looked at.

    Code (CSharp):
    1.  
    2.     NetworkClient client;
    3.  
    4.     public void OnGUI()
    5.     {
    6.         if (!isLocalPlayer) return;
    7.         if(Input.GetKeyDown(KeyCode.Space))
    8.         {
    9.             MyScoreMessage msg = new MyScoreMessage();
    10.             msg.score = 100;
    11.  
    12.             client.Send(MyMessageTypes.MSG_SCORE, msg);
    13.  
    14.         }
    15.        
    16.     }
    17.  
    18.     public class MyMessageTypes
    19.     {
    20.         public static short MSG_SCORE = 1005;
    21.     };
    22.  
    23.     public class MyScoreMessage : MessageBase
    24.     {
    25.         public int score;
    26.     }
    27.  
    28.  
    and this is what I've got on a script in the scene which extends NetworkBehaviour.

    Code (CSharp):
    1.  [ServerCallback] // only call this on server
    2.     public void ReceiveSomethingOnServer(NetworkMessage netMsg)
    3.     {
    4.         //server does stuff here
    5.     }
    But as it's erroring in the player script, nothing is received here. I'd looking into using the [command] functionality - but I can't find an example it it that I can get working either. Any help would be mucho appreciated.
     
  43. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Read the manual - the part about Cmds.
    Also read the old UNET manual.
    We'll also add more examples later to make this more obvious.
     
    kingbaggot likes this.
  44. kingbaggot

    kingbaggot

    Joined:
    Jun 6, 2013
    Posts:
    15
    this this the manual right ? Just checking !
    https://vis2k.github.io/Mirror/

    I'll go through the UNet Manual & Some examples too. Thanks for putting all this together :)
     
  45. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Yes
     
    kingbaggot likes this.
  46. goldbug

    goldbug

    Joined:
    Oct 12, 2011
    Posts:
    654
    @kingbaggot it is a lot simpler than that:

    Code (CSharp):
    1.  
    2.     public void OnGUI()
    3.     {
    4.         if (!isLocalPlayer) return;
    5.         if(Input.GetKeyDown(KeyCode.Space))
    6.         {
    7.             // this sends a message to the server.   It does not wait for the server to execute it
    8.             CmdSendScore(100);
    9.         }
    10.     }
    11.  
    12.     [Command]
    13.     public CmdSendScore(int score)
    14.     {
    15.           // this gets executed in the server,  with the score the client passed us
    16.     }
    17. }
    18.  
     
    kingbaggot likes this.
  47. Arganth

    Arganth

    Joined:
    Jul 31, 2015
    Posts:
    279
    Just to clarify:
    I would like to use Mirror potential Coop-Play with Peer-to-Peer Networking (not concerned with cheating at all)
    So would it be possible that
    - one person hosts the game using the "serverportion" of mirror
    - the other are able to find joinable games and connect?

    Or i am wrong?
     
  48. antsonthetree

    antsonthetree

    Joined:
    May 15, 2015
    Posts:
    40
    I just updated from a previous Mirror to the latest source asset version and I'm running into a problem. I've reassigned all my network identities and transforms, and when I run my app in host mode my little tank runs around fine and is replicated to the clients. However none of my clients can move at all. Their transforms are not getting updated locally or on the server. The main difference between my code and your example in the project is that I am spawning my tanks using NetworkServer.SpawnWithClientAuthority() - which I have to do because players can switch tanks at runtime etc. This function is coming back with a true return so it seems to be successful. Any thoughts on this?

    EDIT- This only seems to be affecting the transform updates. The clients can still fire their bullets and that is replicated to the server and other clients. They just cannot move.

    Also - my tanks have a Rigidbody component on them and I think that may be related to the issue. I noticed in your NetworkTransformBase you mention that FixedUpdate handles the rigidbody movement and rotation - however there is no FixedUpdate implemented in NetworkTransformBase or NetworkTransform. Maybe somethings missing?
     
    Last edited: Jan 15, 2019 at 8:18 PM
  49. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Peer-to-peer is a dead end. Just let people host the server, they can do that on their own computer too (port forwarding).
     
    Arganth likes this.
  50. vis2k

    vis2k

    Joined:
    Sep 4, 2015
    Posts:
    2,816
    Take a look at the 'move' example from the current version on github. It uses local authority too, and it works there.
    If you think you found a bug then please open an issue on github and tell us how to reproduce it.