Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Cannot Achieve NAT punch-through.

Discussion in 'Multiplayer' started by InvaderStudios, Jan 16, 2011.

  1. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    Hello. I am following the M2H networking tutorial. Everything seems to work great. Right now I can only get players that have a wired connections to play. I spoke with M2H and they said (as I expected) that it was a problem with a NAT punch-through. I am using Unity's master server. Here is the game, http://www.invaderstudios.com/game any suggestions will help. Thank you very much!
     
  2. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Suggestion: Host your own master server - connection tester - nat facilitator

    The default one isn't meant for production and its nat facilitator has a good chance of not working normally
     
  3. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    Thats what I was thinking should be my next step.

    Do you know if DimeRocker's master server is still up and running?

    Also I get this message in the console-

    WARNING: 'UnityEngine.ConnectionTesterStatus.PrivateIPHasNATPunchThrough' is obselet. Not longer returned, use newer connection tester enums instead.
     
    Last edited: Jan 16, 2011
  4. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    In the Help files, look up the ConnectionTesterStatus class. There should be a code snippet with all of the Unity3 test result values that you can replace into Leepo's 2.6 code.
     
  5. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    What are the help files?
     
  6. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    In a script, type "ConnectionTesterStatus", put your cursor somewhere in that word, and hit F1. :) Those help files.
     
  7. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    Well... that's embarassing. :)
     
  8. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    Invader Studios, I've been having similar problems, I'm trying something different:

    For an individual server that you can connect to (as in, like in the UI code for Leepo's M2H tutorial:)

    MenuGUI.js section, in OnGUI():
    Code (csharp):
    1. element = connection.hostData[myElement];
    2.        
    3. GUILayout.BeginHorizontal();
    4.  
    5. // Do not display NAT enabled games if we cannot do NAT punchthrough
    6. if ( !( connection.filterNATHosts  element.useNat ) )
    7. {
    8.   aHost=1;
    9.   var buttonText : String = element.gameName + " (" + element.connectedPlayers + "/" + element.playerLimit + ")";
    10.                    
    11.   GUI.color = Color( 0.8, 0.8,0.2, 1 );
    12.   if( GUILayout.Button( buttonText ) )
    13.   {
    14.     // Connect to the server.
    15.     connection.Connect( element );
    16.            
    17.     // Read the gameScene info, load that level.
    18.     gameScene = parseInt( element.comment );
    19.     Debug.Log( "gameScene is: " + gameScene );
    20.            
    21.     // In GUI Phase 5, the level is loaded or an error message shown.
    22.     phase = 5;
    23. }
    Connection.js:
    Code (csharp):
    1. function Connect( hostInfo : HostData ) : void
    2. {
    3.   Debug.Log( "Connection: Connecting to " + hostInfo.ip + ":" + hostInfo.port + " with NAT puncthrough." );
    4.   Network.Connect( hostInfo );
    5.   nowConnecting = true;
    6. }
    EDIT!
    Using an overload of Network.Connect that utilizes GUID information is, according to the F1 help files, the ONLY way to achieve client-side NAT puncthrough. I'm testing this to make sure it's entirely accurate. Network.Connect overloads capable of this are:

    Code (csharp):
    1. Network.Connect( GUID );
    2. Network.Connect( GUID, Password );
     
    Last edited: Jan 19, 2011
  9. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    Thanks for that information!
     
  10. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    I've solved the GUID problem, try Laser Cat in my signature. Make sure the version is later than 0.5.0.
     
  11. univtydev0008

    univtydev0008

    Joined:
    Jan 19, 2011
    Posts:
    41
    Hey guys ive been keeping an eye on this thread the last few days as i am having a problem with the NAT Punchthrough aswell.Asvarduil could u please help me to understand how to use the GUID? I am new to networking and it would be of great help to get my game started with multiplayer. Or could u be so kind as to lead me in the right direction, i am using the M2H Example 2 code and trying to figure out where to and how to implement the GUID u mentioned..


    Thanks Again!
     
  12. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    First, I would use Example 4, as that's what I used to get to the code I got.

    In the Menu GUI code, find the part where it shows games being hosted. There will be a section like this:

    Code (csharp):
    1. scrollPosition = GUILayout.BeginScrollView( scrollPosition );
    2.  
    3.     var aHost : int = 0;
    4.        
    5.     if( connection.sortedList  connection.sortedList.length >= 1 )
    6.     {
    7.       for( var myElement in connection.sortedList )
    8.       {
    9.         element = connection.hostData[myElement];
    10.        
    11.         GUILayout.BeginHorizontal();
    12.  
    13.         // Do not display NAT enabled games if we cannot do NAT punchthrough
    14.         if ( !( connection.filterNATHosts  element.useNat ) )
    15.         {
    16.           aHost=1;
    17.           var buttonText : String = element.gameName + " (" + element.connectedPlayers + "/" + element.playerLimit + ")";
    18.                    
    19.           GUI.color = Color( 0.8, 0.8,0.2, 1 );
    20.           if( GUILayout.Button( buttonText ) )
    21.           {
    22.             // Connect to the server.
    23.             connection.Connect( element );
    24.            
    25.             // Read the gameScene info, load that level.
    26.             gameScene = parseInt( element.comment );
    27.             Debug.Log( "gameScene is: " + gameScene );
    28.            
    29.             //Application.LoadLevel( gameScene );
    30.             phase = 5;
    31.           }
    32.           GUILayout.Space( 1 );
    33.         }
    34.         GUILayout.EndHorizontal(); 
    The part you want to keep in mind is the GUILayout.Button() if statement. Keep that open.

    Now, find the menu connect code. You're going to want to rewrite the Connect() function slightly:

    Code (csharp):
    1. function Connect( hostInfo : HostData ) : void
    2. {
    3.   if( hostInfo.useNat ) { Network.Connect( hostInfo.guid ); }
    4.   else                  { Network.Connect( hostInfo ); }
    5.  
    6.   nowConnecting = true;
    7. }
    Network.Connect( hostInfo.guid ) is the only way to achieve NAT punchthrough in Unity3. Go back to your menu code. Remember the if() block? There will be a "xxxxx.Connect()" call in there. Simply pass the whole "element" as the argument to the Connect function, like I already did above.

    I'll be uploading a Unity3 Master Server starting point package very soon, that will detail more about this process, and some out-of-the-box code to help your project, most likely on the Asset Store.
     
  13. univtydev0008

    univtydev0008

    Joined:
    Jan 19, 2011
    Posts:
    41
    Thanks for the help Asvarduil, however this did not fix my problem = ( i did all the steps mentioned....and can see the other player on the masterserver list but am unable to connect successfully to eachother...
     
  14. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    Well, there's more to it than that, also. You also need each person to pre-check what their connection can or cannot do. The 2.6 M2H code needs a slight modification to work.

    In that code, find their TestConnection() function. Replace it with this:

    Code (csharp):
    1. function TestConnection() : void
    2. {
    3.   natCapable = Network.TestConnection();
    4.  
    5.   switch( natCapable )
    6.   {
    7.     case ConnectionTesterStatus.Error:
    8.       testMessage = "Problem determining NAT capabilities";
    9.       errorMessage = "Test complete.  Couldn't determine NAT punchthrough ability.";
    10.       doneTestingNAT = true;
    11.       break;
    12.            
    13.     case ConnectionTesterStatus.Undetermined:
    14.       testMessage = "Undetermined NAT capabilities";
    15.       errorMessage = "Testing connection...";
    16.       doneTestingNAT = false;
    17.       break;
    18.      
    19.     case ConnectionTesterStatus.NATpunchthroughFullCone:
    20.     case ConnectionTesterStatus.NATpunchthroughAddressRestrictedCone:
    21.       testMessage = "NAT can punchthrough as necessary.";
    22.       errorMessage = "";
    23.       doneTestingNAT = true;
    24.       useNAT = true;
    25.       break;
    26.      
    27.     case ConnectionTesterStatus.LimitedNATPunchthroughPortRestricted:
    28.         testMessage = "Everyone except Symmetric NATs can connect.";
    29.         errorMessage = "Test complete.  Some players cannot join your games.";
    30.         doneTestingNAT = true;
    31.         useNAT = true;
    32.         break;
    33.    
    34.     case ConnectionTesterStatus.LimitedNATPunchthroughSymmetric:
    35.         testMessage = "NAT Punchthrough is limited to asymmetric NAT systems.";
    36.         errorMessage = "Test complete.  Your NAT punchthrough is limited, do not host games.";
    37.         doneTestingNAT = true;
    38.         useNAT = true;
    39.         break;
    40.                    
    41.     case ConnectionTesterStatus.PublicIPIsConnectable:
    42.         testMessage = "Directly connectable public IP address.";
    43.         errorMessage = "";
    44.         doneTestingNAT = true;
    45.         useNAT = false;
    46.         break;
    47.        
    48.     // This case is a bit special as we now need to check if we can
    49.     // cicrumvent the blocking by using NAT punchthrough
    50.     case ConnectionTesterStatus.PublicIPPortBlocked:
    51.         testMessage = "Non-connectble public IP address (port " + address.ipPort + " blocked), running a server is impossible.";
    52.         errorMessage = "Test complete.  Port " + address.ipPort + " is blocked.  A server can't be started.";
    53.         // If no NAT punchthrough test has been performed on this public IP, force a test
    54.         if ( !probingPublicIP )
    55.         {
    56.           Debug.Log( "Testing if firewall can be circumvented" );
    57.           natCapable = Network.TestConnectionNAT();
    58.           probingPublicIP = true;
    59.           timer = Time.time + 10;
    60.           useNAT = false;
    61.         }
    62.         // NAT punchthrough test was performed but we still get blocked
    63.         else if( Time.time > timer )
    64.         {
    65.           probingPublicIP = false;      // reset
    66.           doneTestingNAT = true;
    67.           useNAT = true;
    68.         }
    69.         break;
    70.        
    71.     case ConnectionTesterStatus.PublicIPNoServerStarted:
    72.         testMessage = "Server not started, it is needed to check ability to connect with server. Restart the test when ready.";
    73.         break;
    74.    
    75.     default:
    76.         testMessage = "Error in test routine, got " + natCapable;
    77.         errorMessage = "Test complete.  There was an error in the connection test: " + natCapable;
    78.   }
    79.  
    80.   if( doneTestingNAT )
    81.   {
    82.     Debug.Log( "Test Result: " + testMessage + "\n" +
    83.                "NAT Capability: " + natCapable + "\n" +
    84.                "Probing Public IP: " + probingPublicIP + "\n" +
    85.                "Done Testing NAT: " + doneTestingNAT );
    86.   }
    87.  
    88. }
    This code is U3-friendly and should work a little better. The way I trigger it is:

    Code (csharp):
    1. function Awake() : void
    2. {
    3.   // There's more here...but I omitted it, because it's
    4.   // not relevant.
    5.  
    6.   PretestConnection();
    7. }
    8.  
    9. function PretestConnection
    10. {
    11.   while( !doneTestingNAT )
    12.   {
    13.     TestConnection();
    14.     yield;
    15.   }
    16. }
    On game startup - presuming you have an object with this code in your first loaded scene - your players should be automatically testing their own connections. This is particularly important for when they start servers, as that's where the real ickiness of NAT happens; the client side of it is as simple as the Connect() function I already gave, as that Connect knows what to do based on whether or not the server requires NAT (which, you tell it in HostGame()...drat, I forgot that. Here ya go.)

    Code (csharp):
    1. function HostGame( players : int, port : int, scene : int ) : void
    2. {
    3.   // Ensure that we have completed the network test...
    4.   if( natCapable == ConnectionTesterStatus.Undetermined )
    5.   {
    6.     errorMessage = "The connection test isn't complete.  You can't connect until it is.";
    7.     return;
    8.   }
    9.  
    10.   // Make sure that there's a number of players for a game.
    11.   errorMessage = "Starting up a game server...";
    12.   if( players < 1 ) { players = 1; }
    13.  
    14.   // Tell clients what scene to load...
    15.   var descData : String = scene + "";
    16.   ambassador.gameDesc = descData;
    17.  
    18.   Network.InitializeServer( players,port,useNAT );
    19. }
    Integrate all of that, make it work with the variables you already have set up, then try some connection tests.
     
  15. univtydev0008

    univtydev0008

    Joined:
    Jan 19, 2011
    Posts:
    41
    Thanks for the help Asvarduil, u are the only person to try to help me out with this issue ive been having for a few weeks now lol...i have got all the code in place u provided and no errors...waiting til 2morrow for my buddy to get on so we can test to see if we can get a successfull connection..the pretest script u made tells me i have limited punchthrough and should not host a server....does that mean anything bad? lol thanks again man i owe u big time if it works!
     
  16. Udyrfrykte

    Udyrfrykte

    Joined:
    Feb 14, 2010
    Posts:
    156
    I would like to mention that the M2H tutorial is outdated.
    I'm in the progress myself of reworking the network code after the move to Unity 3.x.
     
  17. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    Thanks for the help Asvaduil. I'm no programmer but I spent some time reading what you said and I am getting a few errors. First off, I am not using the Example_4 demo. I was wondering if all the scripts from the other examples are all linked together? Here is my code.

    Menu_GUI.js

    Code (csharp):
    1.  
    2. /*
    3. *  This file is part of the Unity networking tutorial by M2H (http://www.M2H.nl)
    4. *  The original author of this code is Mike Hergaarden, even though some small parts
    5. *  are copied from the Unity tutorials/manuals.
    6. *  Feel free to use this code for your own projects, drop us a line if you made something exciting!
    7. */
    8. #pragma strict
    9. #pragma implicit
    10. #pragma downcast
    11.  
    12. private var windowRect1;
    13. private var windowRect2;
    14. private var windowRect3;
    15.  
    16. static var playNowMode : boolean = false;
    17. static var advancedMode : boolean = false;
    18. static var playNowModeStarted  : float = 0.0;
    19.  
    20. static var myPlayerName : String = "MyPlayerName";
    21.  
    22. //GUI vars
    23. private var hostPlayers : int = 8;
    24. private var hostPort : int;
    25. private var connectPort : int;
    26. private var connectIP : String = "";
    27.  
    28. private var multiplayerScript : Menu_multiplayerCode;
    29. private var currentMenu : String = "";
    30.  
    31.  
    32. function Awake ()
    33. {  
    34.     Screen.lockCursor=false;   
    35.    
    36.     myPlayerName = PlayerPrefs.GetString("playerName");
    37.    
    38.     multiplayerScript = GetComponent(Menu_multiplayerCode);
    39.  
    40.     connectPort = hostPort = multiplayerScript.serverPort;
    41.     connectIP = "127.0.0.1";
    42.    
    43.     windowRect1 = Rect (Screen.width/2-310,Screen.height/2-90,380,280);
    44.     windowRect2 = Rect (Screen.width/2+85,Screen.height/2-90,220,100);
    45.     windowRect3 = Rect (Screen.width/2+85,Screen.height/2+55,220,100);
    46.    
    47.     playNowMode=false;
    48.     advancedMode=false;
    49. }
    50.  
    51.  
    52.  
    53.  
    54. function OnGUI ()
    55. {      
    56.     //If we've connected;  load the game when it's ready to load
    57.     if(Network.isClient || Network.isServer){
    58.         //Since we're connected, load the game
    59.         GUI.Box(Rect(Screen.width/4+0,Screen.height/2-30,450,50), "");
    60.         if(Application.CanStreamedLevelBeLoaded ((Application.loadedLevel+1))){
    61.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-25,285,150), "Starting the game!");
    62.             Application.LoadLevel((Application.loadedLevel+1));
    63.         }else{
    64.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-25,285,150), "Loading the game: "+Mathf.Floor(Application.GetStreamProgressForLevel((Application.loadedLevel+1))*100)+" %");
    65.         }  
    66.         return;
    67.     }
    68.    
    69.    
    70.     //Dirty error message popup
    71.     if(multiplayerScript.errorMessage  multiplayerScript.errorMessage!=""){
    72.         GUI.Box(Rect(Screen.width/2-100,Screen.height/2-60,200,60), "Error");
    73.         GUI.Label(Rect(Screen.width/2-90,Screen.height/2-50,180,50), multiplayerScript.errorMessage);
    74.         if(GUI.Button(Rect(Screen.width/2+40,Screen.height/2-30,50,20), "Close")){
    75.             multiplayerScript.errorMessage="";
    76.         }
    77.     }  
    78.    
    79.     if(playNowMode){
    80.         playNowFunction();
    81.     }else if(advancedMode){
    82.        
    83.         if(!multiplayerScript.errorMessage || multiplayerScript.errorMessage==""){ //Hide windows on error
    84.             if(GUI.Button(Rect(455,90,140,30), "Back to main menu")){
    85.                 currentMenu="";
    86.                 advancedMode=false;
    87.             }
    88.             windowRect1 = GUILayout.Window (0, windowRect1, listGUI, "Join a game via the list");  
    89.             windowRect2 = GUILayout.Window (1, windowRect2, directConnectGUIWindow, "Directly join a game via an IP"); 
    90.             windowRect3 = GUILayout.Window (2, windowRect3, hostGUI, "Host a game");
    91.         }  
    92.        
    93.     }else{     
    94.         GUI.Box (Rect (90, 180, 260, 105), "Playername");
    95.         GUI.Label (Rect (100, 195, 250, 100), "Please enter your name:");
    96.        
    97.         myPlayerName = GUI.TextField (Rect (178, 215, 147, 27), myPlayerName); 
    98.         if(GUI.changed){
    99.             //Save the name changes
    100.             PlayerPrefs.SetString("playerName", myPlayerName);
    101.         }
    102.        
    103.         if(myPlayerName==""){
    104.             GUI.Label (Rect (100, 240, 260, 100), "After entering your name you can start playing!");
    105.             return;
    106.         }
    107.        
    108.         GUI.Label (Rect (100, 240, 260, 100), "Click on quickplay to start playing right away!");
    109.                
    110.         if(GUI.Button(Rect(400,150,150,30), "Quickplay") ){
    111.             currentMenu="playnow";
    112.             playNowMode=true;
    113.             playNowModeStarted=Time.time;      
    114.         }
    115.         if(GUI.Button(Rect(400,245,150,30), "Advanced") ){
    116.             currentMenu="advanced";
    117.             advancedMode=true;
    118.         }
    119.            
    120.     }
    121. }
    122.  
    123.  
    124. function playNowFunction(){
    125.         if(GUI.Button(Rect(490,185,75,20), "Cancel")){
    126.             Network.Disconnect();
    127.             currentMenu="";
    128.             playNowMode=false;
    129.         }
    130.        
    131.         GUI.Box(Rect(Screen.width/4+0,Screen.height/2-50,420,50), "");
    132.  
    133.         if(multiplayerScript.tryingToConnectPlayNowNumber>=10){
    134.             //If players get fed up waiting they can choose to start a host right away
    135.             if(GUI.Button(Rect(400,185,75,20), "Just host")){
    136.                 multiplayerScript.StartHost(hostPlayers, multiplayerScript.serverPort);
    137.             }
    138.         }
    139.        
    140.         var connectStatus = multiplayerScript.PlayNow(playNowModeStarted);
    141.        
    142.         if(connectStatus=="failed"){
    143.             //Couldn't find a proper host; host ourselves
    144.             Debug.Log("PlayNow: No games hosted, so hosting one ourselves");   
    145.             multiplayerScript.StartHost(7, multiplayerScript.serverPort);              
    146.         }else{
    147.             //Still trying to connect to the first hit
    148.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-45,385,50), connectStatus);
    149.         }
    150. }
    151.  
    152.  
    153. function hostGUI(id : int){
    154.  
    155.     GUILayout.BeginVertical();
    156.     GUILayout.Space(10);
    157.     GUILayout.EndVertical();
    158.    
    159.     GUILayout.BeginHorizontal();
    160.     GUILayout.Space(10);
    161.         GUILayout.Label("Use port: ");
    162.         hostPort = parseInt(GUILayout.TextField(hostPort.ToString(), GUILayout.MaxWidth(75)));
    163.     GUILayout.Space(10);
    164.     GUILayout.EndHorizontal(); 
    165.    
    166.     GUILayout.BeginHorizontal();
    167.     GUILayout.Space(10);
    168.         GUILayout.Label("Players: ");
    169.         hostPlayers = parseInt(GUILayout.TextField(hostPlayers.ToString(), GUILayout.MaxWidth(75)));
    170.     GUILayout.Space(10);
    171.     GUILayout.EndHorizontal();
    172.    
    173.    
    174.     GUILayout.BeginHorizontal();
    175.     GUILayout.FlexibleSpace();
    176.         // Start a new server
    177.         if (GUILayout.Button ("Start hosting a server")){
    178.             multiplayerScript.StartHost(hostPlayers, hostPort);
    179.         }          
    180.     GUILayout.FlexibleSpace();
    181.     GUILayout.EndHorizontal();
    182. }
    183.  
    184.  
    185. function directConnectGUIWindow(id : int){
    186.  
    187.     GUILayout.BeginVertical();
    188.     GUILayout.Space(5);
    189.     GUILayout.EndVertical();
    190.     GUILayout.Label(multiplayerScript.connectionInfo);
    191.        
    192.     if(multiplayerScript.nowConnecting){
    193.         GUILayout.BeginHorizontal();
    194.         GUILayout.FlexibleSpace();
    195.         GUILayout.Label("Trying to connect to "+connectIP+":"+connectPort);
    196.         GUILayout.FlexibleSpace();
    197.         GUILayout.EndHorizontal();
    198.        
    199.     } else {       
    200.  
    201.         GUILayout.BeginHorizontal();
    202.         GUILayout.Space(10);
    203.             connectIP = GUILayout.TextField(connectIP, GUILayout.MinWidth(70));
    204.             connectPort = parseInt(GUILayout.TextField(connectPort+""));
    205.         GUILayout.Space(10);
    206.         GUILayout.EndHorizontal();
    207.        
    208.        
    209.        
    210.         GUILayout.BeginHorizontal();
    211.         GUILayout.Space(10);
    212.         GUILayout.FlexibleSpace();
    213.            
    214.         if (GUILayout.Button ("Connect"))
    215.         {
    216.             multiplayerScript.Connect(connectIP, connectPort);
    217.         }  
    218.        
    219.         GUILayout.FlexibleSpace();
    220.         GUILayout.EndHorizontal();
    221.    
    222.     }
    223.    
    224. }
    225.  
    226. private var scrollPosition : Vector2;
    227.  
    228. function listGUI (id : int) {
    229.    
    230.         GUILayout.BeginVertical();
    231.         GUILayout.Space(6);
    232.         GUILayout.EndVertical();
    233.    
    234.        
    235.         GUILayout.BeginHorizontal();
    236.         GUILayout.Space(200);
    237.  
    238.         // Refresh hosts
    239.         if (GUILayout.Button ("Refresh available Servers"))
    240.         {
    241.             multiplayerScript.FetchHostList(true);
    242.         }
    243.         multiplayerScript.FetchHostList(false);
    244.        
    245.         GUILayout.FlexibleSpace();
    246.         GUILayout.EndHorizontal();
    247.  
    248.         //scrollPosition = GUI.BeginScrollView (Rect (0,60,385,200),    scrollPosition, Rect (0, 100, 350, 3000));
    249.         scrollPosition = GUILayout.BeginScrollView( scrollPosition );
    250.  
    251.     var aHost : int = 0;
    252.        
    253.     if( connection.sortedList  connection.sortedList.length >= 1 )
    254.     {
    255.       for( var myElement in connection.sortedList )
    256.       {
    257.         element = connection.hostData[myElement];
    258.        
    259.         GUILayout.BeginHorizontal();
    260.  
    261.         // Do not display NAT enabled games if we cannot do NAT punchthrough
    262.         if ( !( connection.filterNATHosts  element.useNat ) )
    263.         {
    264.           aHost=1;
    265.           var buttonText : String = element.gameName + " (" + element.connectedPlayers + "/" + element.playerLimit + ")";
    266.                    
    267.           GUI.color = Color( 0.8, 0.8,0.2, 1 );
    268.           if( GUILayout.Button( buttonText ) )
    269.           {
    270.             // Connect to the server.
    271.             connection.Connect( element );
    272.            
    273.             // Read the gameScene info, load that level.
    274.             gameScene = parseInt( element.comment );
    275.             Debug.Log( "gameScene is: " + gameScene );
    276.            
    277.             //Application.LoadLevel( gameScene );
    278.             phase = 5;
    279.           }
    280.           GUILayout.Space( 1 );
    281.         }
    282.         GUILayout.EndHorizontal();
    283.             }
    284.         }      
    285.         GUILayout.EndScrollView ();
    286.         if(aHost==0){
    287.             GUILayout.Label("No games hosted at the moment..");
    288.         }
    289. }
    290.  

    Other code in next post. Along with error messages
     
  18. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    And here is Menu_multiplayerCode.js

    Code (csharp):
    1.  
    2. /*
    3. *  This file is part of the Unity networking tutorial by M2H (http://www.M2H.nl)
    4. *  The original author of this code is Mike Hergaarden, even though some small parts
    5. *  are copied from the Unity tutorials/manuals.
    6. *  Feel free to use this code for your own projects, drop us a line if you made something exciting!
    7. */
    8. #pragma strict
    9. #pragma implicit
    10. #pragma downcast
    11.  
    12. private var windowRect1;
    13. private var windowRect2;
    14. private var windowRect3;
    15.  
    16. static var playNowMode : boolean = false;
    17. static var advancedMode : boolean = false;
    18. static var playNowModeStarted  : float = 0.0;
    19.  
    20. static var myPlayerName : String = "MyPlayerName";
    21.  
    22. //GUI vars
    23. private var hostPlayers : int = 8;
    24. private var hostPort : int;
    25. private var connectPort : int;
    26. private var connectIP : String = "";
    27.  
    28. private var multiplayerScript : Menu_multiplayerCode;
    29. private var currentMenu : String = "";
    30.  
    31.  
    32. function Awake ()
    33. {  
    34.     Screen.lockCursor=false;   
    35.    
    36.     myPlayerName = PlayerPrefs.GetString("playerName");
    37.    
    38.     multiplayerScript = GetComponent(Menu_multiplayerCode);
    39.  
    40.     connectPort = hostPort = multiplayerScript.serverPort;
    41.     connectIP = "127.0.0.1";
    42.    
    43.     windowRect1 = Rect (Screen.width/2-310,Screen.height/2-90,380,280);
    44.     windowRect2 = Rect (Screen.width/2+85,Screen.height/2-90,220,100);
    45.     windowRect3 = Rect (Screen.width/2+85,Screen.height/2+55,220,100);
    46.    
    47.     playNowMode=false;
    48.     advancedMode=false;
    49. }
    50.  
    51.  
    52.  
    53.  
    54. function OnGUI ()
    55. {      
    56.     //If we've connected;  load the game when it's ready to load
    57.     if(Network.isClient || Network.isServer){
    58.         //Since we're connected, load the game
    59.         GUI.Box(Rect(Screen.width/4+0,Screen.height/2-30,450,50), "");
    60.         if(Application.CanStreamedLevelBeLoaded ((Application.loadedLevel+1))){
    61.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-25,285,150), "Starting the game!");
    62.             Application.LoadLevel((Application.loadedLevel+1));
    63.         }else{
    64.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-25,285,150), "Loading the game: "+Mathf.Floor(Application.GetStreamProgressForLevel((Application.loadedLevel+1))*100)+" %");
    65.         }  
    66.         return;
    67.     }
    68.    
    69.    
    70.     //Dirty error message popup
    71.     if(multiplayerScript.errorMessage  multiplayerScript.errorMessage!=""){
    72.         GUI.Box(Rect(Screen.width/2-100,Screen.height/2-60,200,60), "Error");
    73.         GUI.Label(Rect(Screen.width/2-90,Screen.height/2-50,180,50), multiplayerScript.errorMessage);
    74.         if(GUI.Button(Rect(Screen.width/2+40,Screen.height/2-30,50,20), "Close")){
    75.             multiplayerScript.errorMessage="";
    76.         }
    77.     }  
    78.    
    79.     if(playNowMode){
    80.         playNowFunction();
    81.     }else if(advancedMode){
    82.        
    83.         if(!multiplayerScript.errorMessage || multiplayerScript.errorMessage==""){ //Hide windows on error
    84.             if(GUI.Button(Rect(455,90,140,30), "Back to main menu")){
    85.                 currentMenu="";
    86.                 advancedMode=false;
    87.             }
    88.             windowRect1 = GUILayout.Window (0, windowRect1, listGUI, "Join a game via the list");  
    89.             windowRect2 = GUILayout.Window (1, windowRect2, directConnectGUIWindow, "Directly join a game via an IP"); 
    90.             windowRect3 = GUILayout.Window (2, windowRect3, hostGUI, "Host a game");
    91.         }  
    92.        
    93.     }else{     
    94.         GUI.Box (Rect (90, 180, 260, 105), "Playername");
    95.         GUI.Label (Rect (100, 195, 250, 100), "Please enter your name:");
    96.        
    97.         myPlayerName = GUI.TextField (Rect (178, 215, 147, 27), myPlayerName); 
    98.         if(GUI.changed){
    99.             //Save the name changes
    100.             PlayerPrefs.SetString("playerName", myPlayerName);
    101.         }
    102.        
    103.         if(myPlayerName==""){
    104.             GUI.Label (Rect (100, 240, 260, 100), "After entering your name you can start playing!");
    105.             return;
    106.         }
    107.        
    108.         GUI.Label (Rect (100, 240, 260, 100), "Click on quickplay to start playing right away!");
    109.                
    110.         if(GUI.Button(Rect(400,150,150,30), "Quickplay") ){
    111.             currentMenu="playnow";
    112.             playNowMode=true;
    113.             playNowModeStarted=Time.time;      
    114.         }
    115.         if(GUI.Button(Rect(400,245,150,30), "Advanced") ){
    116.             currentMenu="advanced";
    117.             advancedMode=true;
    118.         }
    119.            
    120.     }
    121. }
    122.  
    123.  
    124. function playNowFunction(){
    125.         if(GUI.Button(Rect(490,185,75,20), "Cancel")){
    126.             Network.Disconnect();
    127.             currentMenu="";
    128.             playNowMode=false;
    129.         }
    130.        
    131.         GUI.Box(Rect(Screen.width/4+0,Screen.height/2-50,420,50), "");
    132.  
    133.         if(multiplayerScript.tryingToConnectPlayNowNumber>=10){
    134.             //If players get fed up waiting they can choose to start a host right away
    135.             if(GUI.Button(Rect(400,185,75,20), "Just host")){
    136.                 multiplayerScript.StartHost(hostPlayers, multiplayerScript.serverPort);
    137.             }
    138.         }
    139.        
    140.         var connectStatus = multiplayerScript.PlayNow(playNowModeStarted);
    141.        
    142.         if(connectStatus=="failed"){
    143.             //Couldn't find a proper host; host ourselves
    144.             Debug.Log("PlayNow: No games hosted, so hosting one ourselves");   
    145.             multiplayerScript.StartHost(7, multiplayerScript.serverPort);              
    146.         }else{
    147.             //Still trying to connect to the first hit
    148.             GUI.Label(Rect(Screen.width/4+10,Screen.height/2-45,385,50), connectStatus);
    149.         }
    150. }
    151.  
    152.  
    153. function hostGUI(id : int){
    154.  
    155.     GUILayout.BeginVertical();
    156.     GUILayout.Space(10);
    157.     GUILayout.EndVertical();
    158.    
    159.     GUILayout.BeginHorizontal();
    160.     GUILayout.Space(10);
    161.         GUILayout.Label("Use port: ");
    162.         hostPort = parseInt(GUILayout.TextField(hostPort.ToString(), GUILayout.MaxWidth(75)));
    163.     GUILayout.Space(10);
    164.     GUILayout.EndHorizontal(); 
    165.    
    166.     GUILayout.BeginHorizontal();
    167.     GUILayout.Space(10);
    168.         GUILayout.Label("Players: ");
    169.         hostPlayers = parseInt(GUILayout.TextField(hostPlayers.ToString(), GUILayout.MaxWidth(75)));
    170.     GUILayout.Space(10);
    171.     GUILayout.EndHorizontal();
    172.    
    173.    
    174.     GUILayout.BeginHorizontal();
    175.     GUILayout.FlexibleSpace();
    176.         // Start a new server
    177.         if (GUILayout.Button ("Start hosting a server")){
    178.             multiplayerScript.StartHost(hostPlayers, hostPort);
    179.         }          
    180.     GUILayout.FlexibleSpace();
    181.     GUILayout.EndHorizontal();
    182. }
    183.  
    184.  
    185. function directConnectGUIWindow(id : int){
    186.  
    187.     GUILayout.BeginVertical();
    188.     GUILayout.Space(5);
    189.     GUILayout.EndVertical();
    190.     GUILayout.Label(multiplayerScript.connectionInfo);
    191.        
    192.     if(multiplayerScript.nowConnecting){
    193.         GUILayout.BeginHorizontal();
    194.         GUILayout.FlexibleSpace();
    195.         GUILayout.Label("Trying to connect to "+connectIP+":"+connectPort);
    196.         GUILayout.FlexibleSpace();
    197.         GUILayout.EndHorizontal();
    198.        
    199.     } else {       
    200.  
    201.         GUILayout.BeginHorizontal();
    202.         GUILayout.Space(10);
    203.             connectIP = GUILayout.TextField(connectIP, GUILayout.MinWidth(70));
    204.             connectPort = parseInt(GUILayout.TextField(connectPort+""));
    205.         GUILayout.Space(10);
    206.         GUILayout.EndHorizontal();
    207.        
    208.        
    209.        
    210.         GUILayout.BeginHorizontal();
    211.         GUILayout.Space(10);
    212.         GUILayout.FlexibleSpace();
    213.            
    214.         if (GUILayout.Button ("Connect"))
    215.         {
    216.             multiplayerScript.Connect(connectIP, connectPort);
    217.         }  
    218.        
    219.         GUILayout.FlexibleSpace();
    220.         GUILayout.EndHorizontal();
    221.    
    222.     }
    223.    
    224. }
    225.  
    226. private var scrollPosition : Vector2;
    227.  
    228. function listGUI (id : int) {
    229.    
    230.         GUILayout.BeginVertical();
    231.         GUILayout.Space(6);
    232.         GUILayout.EndVertical();
    233.    
    234.        
    235.         GUILayout.BeginHorizontal();
    236.         GUILayout.Space(200);
    237.  
    238.         // Refresh hosts
    239.         if (GUILayout.Button ("Refresh available Servers"))
    240.         {
    241.             multiplayerScript.FetchHostList(true);
    242.         }
    243.         multiplayerScript.FetchHostList(false);
    244.        
    245.         GUILayout.FlexibleSpace();
    246.         GUILayout.EndHorizontal();
    247.  
    248.         //scrollPosition = GUI.BeginScrollView (Rect (0,60,385,200),    scrollPosition, Rect (0, 100, 350, 3000));
    249.         scrollPosition = GUILayout.BeginScrollView( scrollPosition );
    250.  
    251.     var aHost : int = 0;
    252.        
    253.     if( connection.sortedList  connection.sortedList.length >= 1 )
    254.     {
    255.       for( var myElement in connection.sortedList )
    256.       {
    257.         element = connection.hostData[myElement];
    258.        
    259.         GUILayout.BeginHorizontal();
    260.  
    261.         // Do not display NAT enabled games if we cannot do NAT punchthrough
    262.         if ( !( connection.filterNATHosts  element.useNat ) )
    263.         {
    264.           aHost=1;
    265.           var buttonText : String = element.gameName + " (" + element.connectedPlayers + "/" + element.playerLimit + ")";
    266.                    
    267.           GUI.color = Color( 0.8, 0.8,0.2, 1 );
    268.           if( GUILayout.Button( buttonText ) )
    269.           {
    270.             // Connect to the server.
    271.             connection.Connect( element );
    272.            
    273.             // Read the gameScene info, load that level.
    274.             gameScene = parseInt( element.comment );
    275.             Debug.Log( "gameScene is: " + gameScene );
    276.            
    277.             //Application.LoadLevel( gameScene );
    278.             phase = 5;
    279.           }
    280.           GUILayout.Space( 1 );
    281.         }
    282.         GUILayout.EndHorizontal();
    283.             }
    284.         }      
    285.         GUILayout.EndScrollView ();
    286.         if(aHost==0){
    287.             GUILayout.Label("No games hosted at the moment..");
    288.         }
    289. }
    290.  


    And these are the errors I am getting.


    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(265,14): BCE0044: expecting :, found '='.
    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(263,34): UCE0001: ';' expected. Insert a semicolon at the end.
    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(263,29): UCE0001: ';' expected. Insert a semicolon at the end.
    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(263,28): BCE0043: Unexpected token: :.
    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(263,10): UCE0001: ';' expected. Insert a semicolon at the end.



    Thanks for your time!
     
  19. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
    Hello,

    I did a small space combat game a few months ago, that what running well on Unity2.6 + my own MasterServer/Facilitator/ConnectionTester dedicater server... All was working really fine, Nat Punchthrough was ok too.


    I did move to Unity 3 , and started to update the servers but ... the ConnectionTest requires now 4 public IP addresses ! , I don't
    have 4 public addresses
    , and running out of time as I am registering the Kongregate Contest ....

    I don'ta have much time to go back in what was working, I have to focus on the game code, but , how can I do to run a ConnectionTester !?
    I built every thing , I moved it on my dedicated server , I see I am creating sessions , enumeration etc ... ok , but with the
    ConnectionTester I am having problems with Nat punchthrough... and that is normal in fact.


    What can I do to complete the game net code , can I use Unity Servers until the End of the Contest ?

    if yes, what shall I put here :


    MasterServer.ipAddress = ???? ;
    MasterServer.port = ??? ;
    Network.natFacilitatorIP = ????;
    Network.natFacilitatorPort = ????;
    Network.connectionTesterIP = ????;
    Network.connectionTesterIP =????;
    Network.connectionTesterPort = ????;



    Thanks for your feedback !
     
  20. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    MasterServer ipAddress and port, Network.natFacilitatorIP and natFacilitatorPort, and the connectionTester addresses should all be provided by Unity - by default, they point to Unity Tech's Master Server.
     
  21. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
    Hi Asvarduil,

    if I let default values, I have this log:
    OnFailedToConnectToMasterServer(info)=>
    "The connection request to master server at 72.52.207.14:23466 failed. Are you sure it can be "connected to?

    One important question to me:
    --------------------------------------------
    With the latest version of the ConnectionTester , the server does not start if it doesn't find 4 public address on the
    machine ... do you have the trouble ? I looked at the previous version (for 2.6) and this was not done this way.

    How did you solve the issue on your server ?

    Cheers
     
  22. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    I'm using the Unity Master Server...and funny enough I've been having trouble now when I try to test Laser Cat, the exact same thing.

    The Unity Master Server could be down...

    EDIT: I think the Unity Master Server is down. Try Laser Cat in my signature, you pretty much can't start a game at all - I've been getting my little in-game "Connection to :0 Ended." message when I try to host games.

    If you use my "Join Game" button, then hit "Refresh", it is throwing "Couldn't talk to the Master Server", which means it's down as it's pointing to Unity Tech's server.
     
    Last edited: Jan 20, 2011
  23. iceshaft07

    iceshaft07

    Joined:
    Jul 23, 2010
    Posts:
    293
    I should have jumped in this thread earlier.

    I think the Master Server is down, it isn't working for our deployed game. Servers were working previously to today, and the build hasn't changed.

    Thinking about this logically, it is around 10:00 PM in Britain, which means one of two things:
    1) UT is working on uploading the Beta Version of the Master Server to the final version (see sticky above) since it is in the evening and "no one will complain".

    2) Something bad happened, and they are out right now, which means nothing can be done til morning.

    Has anyone tried calling them?
     
  24. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
  25. AndrewGrayGames

    AndrewGrayGames

    Joined:
    Nov 19, 2009
    Posts:
    3,821
    mrwhite, the problem is that there is no requirement of addresses unless you want to point to a different master server. UTech's MS is down, our problem for now is as simple as that.

    I'm looking into ways to either A) find another more reliable MS for Laser Cat, or B) ways to host a release MS of my own as well as a "reliable development Master Server" for public use, to provide an alternative to Unity Tech in the event of their server going down (kind of like this.)
     
  26. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
    Asvarduil Do you want to move on mine ? it's a 24/7 managed server
     
  27. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
  28. mrwhite69

    mrwhite69

    Joined:
    May 28, 2009
    Posts:
    15
    ==> YES , Solved
     
  29. InvaderStudios

    InvaderStudios

    Joined:
    Sep 1, 2010
    Posts:
    230
    Im getting this error....any idea why?


    Assets/Example4/MenuAssets/Menu_multiplayerCode.js(103,10): BCE0089: Type 'Menu_multiplayerCode' already has a definition for 'Connect(UnityEngine.HostData)'.
     
  30. KevS

    KevS

    Joined:
    Apr 21, 2010
    Posts:
    51
    Very intersting post and very useful !
    I am also working on the way to connect clients through the master server of Unity and maybe you could help me. When i start a server, it's seems to register to the marster server, the console say :

    Code (csharp):
    1.  
    2. Attempting to connect to master server at 72.52.207.14:23466
    3. UnityEngine.MasterServer:RegisterHost(String, String, String)
    4. Connected to facilitator at 72.52.207.14:50005
    5. Connected to master server at 72.52.207.14:23466
    6. Sent host registration to master server, registering a NAT assisted game as
    7.  "New Game", 1, 9, not password protected, "Alpha 0.01.1"
    8. Received identifier 0 from master server
    9.  
    So i assume my game is registered.
    But when i try to retrieve a list with the MasterServer.RequestHostList and MasterServer.PollHostList functions on the client side, the list seems to be empty :(

    An other thing is that i noticed that if i try to start many servers, they all "Received identifier 0 from master server"

    The TestConnection function return "ConnectionTesterStatus.LimitedNATPunchthroughPortRestricted" for the server(s).

    Have you any idea ? Do you think that the Master Server is out ? I read on many posts that the Unity Master Server is not really usable but i can't build one for the moment :(

    Thanks !
     
    Last edited: Jan 31, 2011
  31. PrimeDerektive

    PrimeDerektive

    Joined:
    Dec 13, 2009
    Posts:
    3,090
    http://forum.unity3d.com/threads/76115-Unity-servers-are-being-migrated Probably this?
     
  32. KevS

    KevS

    Joined:
    Apr 21, 2010
    Posts:
    51
    Maybe :) i read that just after my post xD And i hope :)