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

[RELEASED] MultiOnline : multiplayer online kit - V3 now available

Discussion in 'Assets and Asset Store' started by VirtuElle, Aug 16, 2013.

  1. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, I directly answered on the private message you have sent to me
     
  2. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Hi VirtuElle!

    I have purchased both MultiLan and MultiOnline and I really do enjoy this package and have enjoyed using it so far.

    I initially started using MultiLan to see if this was a good option for what I was shooting for and after feeling good about it purchased MultiOnline.

    But ever since I have purchased MultiOnline and integrated it into my existing code, It has become impossible for a users to host a game and have anyone join it.

    In MultiLan this was not an issue but since using MultiOnline I can no longer use the multiplayer functionality.

    I have opened ports, tested on different networks, computers and so on and I have been going through the forum to see if anyone has had a solution but haven't had much luck so I figured I'd ask directly.

    Do you have any idea why I always get "Impossible to connect to Host" error now what i'm using MultiOnline even with the host having a verified open port (checked using multiple open port tools)?

    I really like this system but I'm feeling I may need to look elsewhere because of the frustration of not being able to host any games.

    Thanks in advance and looking forward to you input.
     
  3. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    That's really strange since ML and MO work in the same way, MO just register all the open games.
    About your installation: do you use ML and MO together, or just MO ? If you use the two systems together, does ML still work ?
    And do you have this same problem if the two players are on a same computer ?
     
  4. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Well I do have them both in my project. When I switched over to MO I imported it into my project and it updated some of the ML scripts and Scenes I believe. So they seem to be working together.

    And how do I just test ML to see if it's working? Do I need to comment out the MO specific code from the different scripts and uncomment the ML specific code.

    I seem to be able to join a game if I host as player on the same computer. So for example, as a player, if I host a game in the Standalone Player, and act as another player in the editor, I have no problems joining the session.

    BUT I have noticed that if I try and host a dedicated server session on my same computer, I cannot join that session as a player from the same computer. It's very odd.
     
  5. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    And Just as Reference this is what happens when I attempt to Join a game with a dedicated server on the same computer.

    This is what the Online Game Lobby Looks like with the "Impossible to Connect to This Host" message Online Game Lobby.png

    And here is the error I see in the Unity editor as the Player attempting to join the Dedicated Server
    Online Game Lobby Error Message.png
     
  6. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    If you have the two asset, you have all the games menu, so if you choose the menu "Network Game", you can create/join a game from ML. So, you can check if ML still works from this menu.

    But your problem is quite strange.
    According to your error message, it seems the game is not really open, it is just registered on the database. Are your sure your installation of MO is correct ?Did you try to install only MO on a new project, to test it with the default maps and players ?
     
  7. killer1171090

    killer1171090

    Joined:
    Feb 23, 2013
    Posts:
    145
    Hello i have 3 qustions i would like to ask about multionline

    1. Does multionline support unity 5.4?
    2. Does multionline support the new UI
    3. Does it work with photon?

    Thanks
     
  8. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi,

    Thanks for your interest about MultiOnline, so, about your questions:
    1. MultiOnline works with Unity 5.4, even if it doesn't uses the new network system. In fact, when you import the project, Unity will automatically upgrades the scripts for make it work with the current version.
    2. No, it uses the old UI system
    3. No, MultiOnline is as an alternative of photon, so it's not made to work with.
     
  9. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Hi again ViruElle,

    Sorry it's taken me a while to respond. I had to step away from this portion of my project to handle some other pressing issues.

    But I was able to check what you asked and get MultiLan's menu and MultiOnline's menu working together.

    So I was able to host a game using Multilan and players joining my game from IP but MultiOnline still does not work.

    Do you have any thoughts on why that may be the case and how I could fix this? If I could get this to work it would be HUGE. I just want to save the players from having to type in IP Addresses if possible.

    Do you think it has something to do with MultiOnline using the incorrect IP address when attempting to connect to a players game since they are more or less using the same tech?
     
  10. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Also, I believe the issue may be coming from the IP Finding service getting the wrong IP. I've noticed in the MultiLan that the Private and/or Public IP in the case for my players is different than the IP found by a standard IP finding service.

    I'm thinking that may be the root of the problem.
     
  11. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Yes, it's possible that the IP which is register is wrong, but there is no reason for this.
    MultiLan uses your private IP as long as you join a game which is on your network. But, if the game is hosted by someone which it out of your network, you have to enter the public ip of the host. Your public IP and your private IP are differents, and one or the other is use depending the context.
    Anyway, you can check the IP service of MO. This service is directly done by for the php scripts which come with MO, so, you can enter this URL and check if the public IP provided is correct:
    URL for your website/(folder - if you have put MO files on a foder)/logUser.php?login=1&userName=userName of your player&pass=password of your Player

    You must have a line like that: Success|Your Player ID|Your Player Name|Player's email|YOUR PUBLIC IP|A login Key

    So, you can check that thie IP you can read here is well your public ip.
    And an other question about it: where did you put the php scripts of MO ? Did you upload the from a webhosting ?
     
  12. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Sorry again for the late reply. Bouncing between projects at the moment.

    So the problem did come from the php file using the public id. In the scenario that I'm using within the parameters of my project, the private ID will always be the correct IP because of our configuration. I went through and changed all the code to reflect what I needed and now I can use MO no problem.

    And I followed the instructions in the tutorial. Everything works good. Eventually I will be changing the web hosting and where the DB is located because of security guidelines for out project but it's worked perfectly for an MVP.

    Thanks for all of your help. This has been really helpful and I'm happy that we have Multiplayer working in the game we're developing.

    I do have one last question, Any hope that you will make a version that supports WebGL? That would be huge as Webplayer is pretty much going to be obsolete and though Standalone will pretty much always work, WebGL is the future of browser based games for Unity.

    Thanks again!
     
  13. DecayGame

    DecayGame

    Joined:
    May 15, 2016
    Posts:
    86
    Someone please help me everything is set up but this happens idk why? my player has a script attacted to it named CGUI that controls the Play button on the character and when there are two players in the scene I have to press the play button twice on each character screen then it gets all weird.


    here is the code to the CGUI Script CSS:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class CGUI : MonoBehaviour {
    6.  
    7.     [HideInInspector] public Character character;
    8.     public Texture crosshair;
    9.     public Texture interactiveActive;
    10.     public Texture interactiveInactive;
    11.     private bool showIneractionMenu = false;
    12.     private bool showMainMenu = true;
    13.     private bool showMainOptionsMenu = false;
    14.     private bool showMainOptionsQualityMenu = false;
    15.     private bool showMainOptionsInputMenu = false;
    16.     private GUIContent healthContent;
    17.     public Texture2D healthIcon;
    18.     private GUIContent privaryWeaponContent;
    19.     private GUIContent secondaryWeaponContent;
    20.    
    21.     public GUIStyle style1;
    22.     public GUIStyle style2;
    23.    
    24.     // Rect for buttons in interaction menu
    25.     private List <Rect> ineractionRectangles = new List<Rect>();
    26.     private List <Rect> indicatorsRectangles = new List<Rect>();
    27.     private List <Rect> usableItemsRectangles = new List<Rect>();
    28.     private List <Rect> mainMenuRectangles = new List<Rect>();
    29.     private List <Rect> controlMenuNameRectangles = new List<Rect>();
    30.     private List <Rect> controlMenuKeyRectangles = new List<Rect>();
    31.  
    32.     // Screen coefficient
    33.     private float screenCoefficientX = 1f;
    34.     private float screenCoefficientY = 1f;
    35.     private int oldScreenWidth;
    36.     private int oldScreenHeight;
    37.  
    38.     private string[] qualitySettingsNames;
    39.  
    40.     private KeyCode keyPressed;
    41.     private List<bool> waitForInput = new List<bool>();
    42.  
    43.     private InteractiveObject activeInteractiveObject;
    44.  
    45.     void Awake () {
    46.         healthContent = new GUIContent ();
    47.         privaryWeaponContent = new GUIContent ();
    48.         secondaryWeaponContent = new GUIContent ();
    49.  
    50.         //Rectangles
    51.         for (int counter = 0; counter < 13; counter++) ineractionRectangles.Add (new Rect (10f, 10f + 50f * counter, 300f, 50f));
    52.         for (int counter = 0; counter < 4; counter++) indicatorsRectangles.Add (new Rect (Screen.width - 310f, Screen.height - 10f - 50f * counter, 300f, 50f));
    53.         for (int counter = 0; counter < 10; counter++) usableItemsRectangles.Add (new Rect (Screen.width - 310f, 10f + 50f * counter, 300f, 50f));
    54.         for (int counter = 0; counter < 14; counter++) mainMenuRectangles.Add (new Rect (((Screen.width - 300f)/2f), 50f * counter, 300f, 50f));
    55.         for (int counter = 0; counter < 20; counter++) {
    56.             if (counter < 11) {
    57.                 controlMenuNameRectangles.Add (new Rect (35f, 60f + 50f * counter, 300f, 50f));
    58.             }
    59.             else {
    60.                 controlMenuNameRectangles.Add (new Rect (645f, 110f + 50f * (counter - 12), 300f, 50f));
    61.             }
    62.         }
    63.         for (int counter = 0; counter < 20; counter++) {
    64.             if (counter < 11) {
    65.                 controlMenuKeyRectangles.Add (new Rect (335f, 60f + 50f * counter, 300f, 50f));
    66.             }
    67.             else {
    68.                 controlMenuKeyRectangles.Add (new Rect (945f, 110f + 50f * (counter - 12), 300f, 50f));
    69.             }
    70.         }
    71.  
    72.         for (int counter = 0; counter < 20; counter++) waitForInput.Add (false);
    73.  
    74.         oldScreenHeight = Screen.height;
    75.         oldScreenWidth = Screen.width;
    76.  
    77.         qualitySettingsNames = QualitySettings.names;
    78.  
    79.         keyPressed = KeyCode.A;
    80.     }
    81.  
    82.     void OnGUI() {
    83.         if (!character.input.isAI) {
    84.             UpdateRectangles ();
    85.  
    86.             if (Input.GetKeyDown (KeyCode.Escape)) {
    87.                 showMainMenu = true;
    88.                 SwitchControl (false);
    89.             }
    90.  
    91.             if (showMainMenu) {
    92.                 UpdateMainMenu ();
    93.             }
    94.             else {
    95.                 if (character.cameraController.isZoom && character.weaponsController.weaponIndex != 2) {
    96.                     Rect crosshairRect = new Rect ((Screen.width - crosshair.width)/2.0f, (Screen.height - crosshair.height)/2.0f, crosshair.width, crosshair.height);
    97.                     GUI.DrawTexture (crosshairRect, crosshair, ScaleMode.ScaleToFit);
    98.                 }
    99.                 if (character.interaction.availableInteractiveObjects.Count > 0) {
    100.                     foreach (InteractiveObject intObj in character.interaction.availableInteractiveObjects) {
    101.                         Vector3 intObjScreenPos = character.cameraController.GetComponent<Camera>().WorldToScreenPoint (intObj.GUIPosition.position);
    102.                         if (intObj == activeInteractiveObject) {
    103.                             float posX = intObjScreenPos.x - (interactiveActive.width/2f) * screenCoefficientX;
    104.                             float posY = Screen.height - intObjScreenPos.y - (interactiveActive.height/2f) * screenCoefficientY;
    105.  
    106.                             Rect intObjRect = new Rect (posX, posY, interactiveActive.width * screenCoefficientX, interactiveActive.height * screenCoefficientY);
    107.                             GUI.DrawTexture (intObjRect, interactiveActive, ScaleMode.ScaleToFit);
    108.                         }
    109.                         else {
    110.                             float posX = intObjScreenPos.x - (interactiveInactive.width/2f) * screenCoefficientX;
    111.                             float posY = Screen.height - intObjScreenPos.y - (interactiveInactive.height/2f) * screenCoefficientY;
    112.  
    113.                             Rect intObjRect = new Rect (posX, posY, interactiveInactive.width * screenCoefficientX, interactiveInactive.height * screenCoefficientY);
    114.                             GUI.DrawTexture (intObjRect, interactiveInactive, ScaleMode.ScaleToFit);
    115.                         }
    116.                     }
    117.                 }
    118.  
    119.                 UpdateIneractionAndInventory ();
    120.                 UpdateIndicators ();
    121.             }
    122.         }
    123.     }
    124.  
    125.     void UpdateRectangles () {
    126.         float screenCoefficientXOld = screenCoefficientX;
    127.         float screenCoefficientYOld = screenCoefficientY;
    128.        
    129.         screenCoefficientX = Screen.width/1280f;
    130.         screenCoefficientY = Screen.height/720f;
    131.        
    132.         // Update size of buttons
    133.         if (screenCoefficientX != screenCoefficientXOld || screenCoefficientY != screenCoefficientYOld) {
    134.             for (int counter = 0; counter < ineractionRectangles.Count; counter++) ineractionRectangles [counter] = new Rect (10f * screenCoefficientX, (10f + 50f * counter) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    135.             for (int counter = 0; counter < indicatorsRectangles.Count; counter++) indicatorsRectangles [counter] = new Rect (Screen.width - 310f * screenCoefficientX, Screen.height - (10f + 50f * counter) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    136.             for (int counter = 0; counter < usableItemsRectangles.Count; counter++) usableItemsRectangles [counter] = new Rect (Screen.width - 310f * screenCoefficientX, (10f + 50f * counter) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    137.             for (int counter = 0; counter < mainMenuRectangles.Count; counter++) mainMenuRectangles[counter] = (new Rect (((Screen.width - 300f * screenCoefficientX)/2f), 50f * counter * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY));
    138.             for (int counter = 0; counter < controlMenuNameRectangles.Count; counter++) {
    139.                 if (counter < 11) {
    140.                     controlMenuNameRectangles [counter] = new Rect (35f * screenCoefficientX, (60f + 50f * counter) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    141.                 }
    142.                 else {
    143.                     controlMenuNameRectangles [counter] = new Rect (645f * screenCoefficientX, (110f + 50f * (counter - 12)) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    144.                 }
    145.             }
    146.             for (int counter = 0; counter < controlMenuKeyRectangles.Count; counter++) {
    147.                 if (counter < 11) {
    148.                     controlMenuKeyRectangles [counter] = new Rect (335f * screenCoefficientX, (60f + 50f * counter) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    149.                 }
    150.                 else {
    151.                     controlMenuKeyRectangles [counter] = new Rect (945f * screenCoefficientX, (110f + 50f * (counter - 12)) * screenCoefficientY, 300f * screenCoefficientX, 50f * screenCoefficientY);
    152.                 }
    153.             }
    154.            
    155.             style1.fontSize = Mathf.RoundToInt (32f * Mathf.Min (screenCoefficientX, screenCoefficientY));
    156.             style1.padding.left =  Mathf.RoundToInt (10f * Mathf.Min (screenCoefficientX, screenCoefficientY));
    157.            
    158.             style2.fontSize = Mathf.RoundToInt (32f * Mathf.Min (screenCoefficientX, screenCoefficientY));
    159.         }
    160.  
    161.     }
    162.  
    163.     void UpdateMainMenu () {
    164.         if (GUI.Button(mainMenuRectangles[13], "Exit", style2)) {
    165.             Application.Quit ();
    166.         }
    167.        
    168.         if (!showMainOptionsMenu) {
    169.             if (GUI.Button(mainMenuRectangles[0], "Play", style2)) {
    170.                 showMainMenu = false;
    171.                 SwitchControl (true);
    172.             }
    173.             if (GUI.Button(mainMenuRectangles[2], "Options", style2)) {
    174.                 showMainOptionsMenu = true;
    175.             }
    176.             if (GUI.Button(mainMenuRectangles[3], "Restart", style2)) {
    177.                 Application.LoadLevel (Application.loadedLevel);
    178.             }
    179.         }
    180.        
    181.         if (showMainOptionsMenu) {
    182.             if (!showMainOptionsQualityMenu && !showMainOptionsInputMenu) {
    183.                 if (GUI.Button(mainMenuRectangles[0], "Back", style2)) {
    184.                     showMainOptionsMenu = false;
    185.                 }
    186.                
    187.                 if (GUI.Button(mainMenuRectangles[2], "Quality", style2)) {
    188.                     showMainOptionsQualityMenu = true;
    189.                 }
    190.                
    191.                 if (GUI.Button(mainMenuRectangles[3], "Input", style2)) {
    192.                     showMainOptionsInputMenu = true;
    193.                 }
    194.                
    195.                 if (Screen.fullScreen) {
    196.                     if (GUI.Button(mainMenuRectangles[4], "Window", style2)) {
    197.                         Screen.SetResolution (oldScreenWidth, oldScreenHeight, false);
    198.                     }
    199.                 }
    200.                 else {
    201.                     if (GUI.Button(mainMenuRectangles[4], "Fullscreen", style2)) {
    202.                         oldScreenHeight = Screen.height;
    203.                         oldScreenWidth = Screen.width;
    204.                         Screen.fullScreen = true;
    205.                     }
    206.                 }
    207.             }
    208.            
    209.             if (showMainOptionsQualityMenu) {
    210.                 if (GUI.Button(mainMenuRectangles[0], "Back", style2)) {
    211.                     showMainOptionsQualityMenu = false;
    212.                 }
    213.                 if (qualitySettingsNames.Length > 0) {
    214.                     for (int counter = 0; counter < qualitySettingsNames.Length; counter++) {
    215.                         if (GUI.Button(mainMenuRectangles[counter + 2], qualitySettingsNames[counter], style2)) {
    216.                             QualitySettings.SetQualityLevel(counter, true);
    217.                         }
    218.                     }
    219.                 }
    220.             }
    221.            
    222.             if (showMainOptionsInputMenu) {
    223.                 if (GUI.Button(mainMenuRectangles[0], "Back", style2)) {
    224.                     showMainOptionsInputMenu = false;
    225.                 }
    226.                
    227.                 DrawInputButton ("forward", character.input.forward, 0);
    228.                 DrawInputButton ("backward", character.input.backward, 1);
    229.                 DrawInputButton ("right", character.input.right, 2);
    230.                 DrawInputButton ("left", character.input.left, 3);
    231.                 DrawInputButton ("sprint", character.input.sprint, 4);
    232.                 DrawInputButton ("aim", character.input.aim, 5);
    233.                 DrawInputButton ("startInteraction", character.input.startInteraction, 6);
    234.                 DrawInputButton ("stopInteraction", character.input.stopInteraction, 7);
    235.                 DrawInputButton ("shoot", character.input.shoot, 8);
    236.                 DrawInputButton ("disarm", character.input.disarm, 9);
    237.                 DrawInputButton ("weaponSlot1", character.input.weaponSlot1, 10);
    238.                 DrawInputButton ("weaponSlot2", character.input.weaponSlot2, 11);
    239.                 DrawInputButton ("nextFireMode", character.input.nextFireMode, 12);
    240.                 DrawInputButton ("dropItemInHands", character.input.dropItemInHands, 13);
    241.                 DrawInputButton ("reloadWeapon", character.input.reloadWeapon, 14);
    242.                 DrawInputButton ("showMenu", character.input.showMenu, 15);
    243.                 DrawInputButton ("hideMenu", character.input.hideMenu, 16);
    244.                 DrawInputButton ("useItem", character.input.useItem, 17);
    245.                
    246.                 for (int counter = 0; counter < waitForInput.Count; counter++) {
    247.                     if (waitForInput[counter]) {
    248.                         if (Event.current.isKey) {
    249.                             keyPressed = Event.current.keyCode;
    250.                             waitForInput[counter] = false;
    251.                             switch (counter) {
    252.                             case 0:
    253.                                 character.input.forward = keyPressed;
    254.                                 break;
    255.                             case 1:
    256.                                 character.input.backward = keyPressed;
    257.                                 break;
    258.                             case 2:
    259.                                 character.input.right = keyPressed;
    260.                                 break;
    261.                             case 3:
    262.                                 character.input.left = keyPressed;
    263.                                 break;
    264.                             case 4:
    265.                                 character.input.sprint = keyPressed;
    266.                                 break;
    267.                             case 5:
    268.                                 character.input.aim = keyPressed;
    269.                                 break;
    270.                             case 6:
    271.                                 character.input.startInteraction = keyPressed;
    272.                                 break;
    273.                             case 7:
    274.                                 character.input.stopInteraction = keyPressed;
    275.                                 break;
    276.                             case 8:
    277.                                 character.input.shoot = keyPressed;
    278.                                 break;
    279.                             case 9:
    280.                                 character.input.disarm = keyPressed;
    281.                                 break;
    282.                             case 10:
    283.                                 character.input.weaponSlot1 = keyPressed;
    284.                                 break;
    285.                             case 11:
    286.                                 character.input.weaponSlot2 = keyPressed;
    287.                                 break;
    288.                             case 12:
    289.                                 character.input.nextFireMode = keyPressed;
    290.                                 break;
    291.                             case 13:
    292.                                 character.input.dropItemInHands = keyPressed;
    293.                                 break;
    294.                             case 14:
    295.                                 character.input.reloadWeapon = keyPressed;
    296.                                 break;
    297.                             case 15:
    298.                                 character.input.showMenu = keyPressed;
    299.                                 break;
    300.                             case 16:
    301.                                 character.input.hideMenu = keyPressed;
    302.                                 break;
    303.                             case 17:
    304.                                 character.input.useItem = keyPressed;
    305.                                 break;
    306.                             }
    307.                         }
    308.                     }
    309.                 }
    310.             }
    311.         }
    312.  
    313.     }
    314.  
    315.     void UpdateIneractionAndInventory () {
    316.         if (showIneractionMenu) {
    317.             //Ineraction Menu
    318.             for (int counter = 0; counter < character.interaction.availableInteractiveObjects.Count; counter++) {
    319.                 if (ineractionRectangles.Count > counter) {
    320.                     if (GUI.Button(ineractionRectangles [counter], character.interaction.availableInteractiveObjects[counter].description, style1)) {
    321.                         character.StartGoToInteraction (character.interaction.availableInteractiveObjects[counter]);
    322.                         ShowMenu (false);
    323.                     }
    324.                 }
    325.                 if (character.interaction.availableInteractiveObjects.Count > 0) {
    326.                     Vector2 mousePos = new Vector2 (Input.mousePosition.x, Screen.height - Input.mousePosition.y);
    327.                     if (ineractionRectangles.Count > counter) {
    328.                         if (ineractionRectangles [counter].Contains (mousePos)) {
    329.                             activeInteractiveObject = character.interaction.availableInteractiveObjects [counter];
    330.                         }
    331.                     }
    332.                 }
    333.             }
    334.            
    335.             //Inventory
    336.             if (character.inventory.usableItems.Count > 0) {
    337.                 for (int counter = 0; counter < character.inventory.usableItems.Count; counter++) {
    338.                     UsableItem usableItem = character.inventory.usableItems[counter];
    339.                     string usableItemString;
    340.                     if (usableItem == character.inventory.selectedItem) {
    341.                         usableItemString = "I " + usableItem.description + " " + ((int) (usableItem.stuffLeft * 100f)).ToString () + "%";
    342.                     }
    343.                     else {
    344.                         usableItemString = "  " + usableItem.description + " " + ((int) (usableItem.stuffLeft * 100f)).ToString () + "%";
    345.                     }
    346.                     if (GUI.Button(usableItemsRectangles[counter], usableItemString, style1)) {
    347.                         ShowMenu (false);
    348.                         character.inventory.selectedItem = usableItem;
    349.                         character.inventory.selectedItemVisualIndex = usableItem.visualIndex;
    350.                     }
    351.                 }
    352.             }
    353.             else {
    354.                 if (GUI.Button(usableItemsRectangles [0], "I -", style1)) return;
    355.             }
    356.         }
    357.         else {
    358.             //Ineraction Menu
    359.             if (character.interaction.closestInteractiveObject) {
    360.                 if (GUI.Button(ineractionRectangles [0], character.interaction.closestInteractiveObject.description, style1)) return;
    361.                 activeInteractiveObject = character.interaction.closestInteractiveObject;
    362.             }
    363.  
    364.             //Inventory
    365.             if (character.inventory.usableItems.Count > 0) {
    366.                 UsableItem usableItem = character.inventory.selectedItem;
    367.                 string stuffLeft = ((int) (usableItem.stuffLeft * 100f)).ToString () + "%";
    368.                 if (GUI.Button(usableItemsRectangles [0], "I " + usableItem.description + " " + stuffLeft, style1)) return;
    369.             }
    370.             else {
    371.                 if (GUI.Button(usableItemsRectangles [0], "I -", style1)) return;
    372.             }
    373.         }
    374.     }
    375.  
    376.     void UpdateIndicators () {
    377.         int health;
    378.         if (character.ragdoll.health > 0) health = (int) character.ragdoll.health;
    379.         else health = 0;
    380.         healthContent.text = health.ToString ();
    381.         healthContent.image = healthIcon;
    382.        
    383.         string privaryWeaponRoundsCount;
    384.         string privaryWeaponMagazinesCount;
    385.         if (character.weaponsController.firearms[0]) {
    386.             privaryWeaponRoundsCount = character.weaponsController.firearms[0].roundsCount.ToString();
    387.             privaryWeaponMagazinesCount = character.weaponsController.magazinesCount[0].ToString();
    388.         }
    389.         else {
    390.             privaryWeaponRoundsCount = "-";
    391.             privaryWeaponMagazinesCount = "-";
    392.         }
    393.         privaryWeaponContent.text = "1 " + privaryWeaponRoundsCount + "/" + privaryWeaponMagazinesCount;
    394.        
    395.         string secondaryWeaponRoundsCount;
    396.         string secondaryWeaponMagazinesCount;
    397.         if (character.weaponsController.firearms[1]) {
    398.             secondaryWeaponRoundsCount = character.weaponsController.firearms[1].roundsCount.ToString();
    399.             secondaryWeaponMagazinesCount = character.weaponsController.magazinesCount[1].ToString();
    400.         }
    401.         else {
    402.             secondaryWeaponRoundsCount = "-";
    403.             secondaryWeaponMagazinesCount = "-";
    404.         }
    405.         secondaryWeaponContent.text = "2 " + secondaryWeaponRoundsCount + "/" + secondaryWeaponMagazinesCount;
    406.        
    407.         if (GUI.Button(indicatorsRectangles [3], healthContent, style1)) return;
    408.         if (GUI.Button(indicatorsRectangles [2], privaryWeaponContent, style1)) return;
    409.         if (GUI.Button(indicatorsRectangles [1], secondaryWeaponContent, style1)) return;
    410.     }
    411.  
    412.     public void ShowMenu (bool show) {
    413.         if (!showMainMenu) {
    414.             showIneractionMenu = show;
    415.             SwitchControl (!show);
    416.         }
    417.     }
    418.    
    419.     void SwitchControl (bool switcher) {
    420.         if (switcher) Cursor.lockState = CursorLockMode.Locked;
    421.         else Cursor.lockState = CursorLockMode.None;
    422.  
    423.         Cursor.visible = !switcher;
    424.         character.cameraController.isControllable = switcher;
    425.         character.input.isCharacterControllable = switcher;
    426.         character.input.vertical = 0f;
    427.         character.input.horizontal = 0f;
    428.         character.input.isMove = false;
    429.         if (!character.input.debugAimOn) character.input.isAim = false;
    430.         character.input.isShootHold = false;
    431.     }
    432.  
    433.     void DrawInputButton (string keyName, KeyCode keyCodeName, int keyIndex) {
    434.         string keyString;
    435.         if (!waitForInput[keyIndex]) keyString = keyCodeName.ToString ();
    436.         else keyString = "?";
    437.         if (GUI.Button(controlMenuKeyRectangles[keyIndex], keyString, style2)) {
    438.             waitForInput[keyIndex] = true;
    439.         }
    440.         if (GUI.Button(controlMenuNameRectangles[keyIndex], keyName.ToString (), style2)) return;
    441.     }
    442. }
    443.  
     
    Last edited: Jul 20, 2016
  14. bshenry

    bshenry

    Joined:
    Aug 3, 2015
    Posts:
    7
    Hey DecayGame,

    It's a bit difficult to decipher what's going on in your code without a detailed look but I will say that the issue with the player movements is a issue with disabling the scripts in the Network Views.

    There is a part in the Documentation that explains it. I found it on page 54 of the "MultiOnlineV3.pdf" in the section 5.1 that's called "Change The Player". I have uploaded an image with an excerpt from the Documentation. Check it out.

    And just as a side note...

    I work at a large tech company as programmer and I would just say to try and work on your code readability. I can decipher your code in general and understand what you're doing but it takes quite a bit of work to do so.

    As a programmer who worked alone for a very long time, I understand where you're coming from. A great practice is to assume that another person will look at your code having of no context of what you're doing and should be able to glance through it and understand what you're doing.

    I see a lot of loops and counters and coefficients doing things (that seem pretty complex) and it makes it hard for me to understand what's happening without some focus. You do a great job of giving you're variables descriptive names and you use comments in good places but I recommend using those comments to explain intentions and to explain why things exist.

    Also, I see a lot of hardcoded numbers (945f, 335f, 32f, etc.) and those are always obscured in code and a year from now if you came back to the code it may be difficult to understand why thy are there. Even if they are temporary hardcoded values, it's better to make them variables (you can even denote them with the prefix "temp") to make readability better.

    Sorry for the long response but since I work in a lot of collaborative environments with people from all across the globe, I've found creating readable code to be an invaluable skill. Figured I'd pass along the knowledge someone once gave to me.

    Best of luck with what you are working on. :)
     

    Attached Files:

  15. DecayGame

    DecayGame

    Joined:
    May 15, 2016
    Posts:
    86
    Thank you :)
     
  16. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Ok many thanks for your message, I'm really glad we finally fixed the problem, and I hope that MO will now help you to develop your game.

    About WebGL I have currently no knowledge about this API, but I read a little about it and it looks very interesting. But one problem it that it require to code the project in JavaScript, and I really prefer use C#. Unity says we can use a code convertor, but that mean convert C# to C, to finally convert it to JavaScript, and, even if Unity says that it is expected to work, personnaly I don't like code conversions. Even if the final code works, we lost a lot of important things during the process, as the semantic, the readability, and so the maintainability (I totally agree with your previous message about writing code ;) It was really interesting to read you)
     
  17. ProfPivec

    ProfPivec

    Joined:
    Sep 21, 2012
    Posts:
    21
    Actually, unity 5 converts the code for you when compiling for WebGL. I write in C# code and after building, it works just fine in WebGL.

    However, my question is do I need any special ports open on the Client? I am not sure about Photon, but Smartfoxserver requires ports to be open and this is a problem with corporate firewalls.

    My second question is if I have a dedicated server, how many clients can I have in the same game with your plugin?

    Thanks in advance.
     
  18. fredmiller12345

    fredmiller12345

    Joined:
    Mar 19, 2015
    Posts:
    4
    Hi... I am thinking about purchasing this asset... but I would like to show you images of my game and ask you a few questions before I purchase... Want to make sure this asset will work with my game before buying...
    Can you email me and we can correspond that way? Thanks.. Ravenger1@aol.com
     
  19. berto654

    berto654

    Joined:
    Aug 19, 2014
    Posts:
    3
    Hi VirtuElle

    I bought Multionline about 2 weeks ago and I'm happy with the product.
    but the only problem I'm having is implementing the RPC so I can see everything in the scene at the same time
    between the host and the clients

    in the scene the only stuff I can see are the players but I want it so you can see the stuff that were RPC instantiated

    thanks in advance
    berto_654@hotmail.com.au
     
  20. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hello, I'm so sorry, I couldn't answer you earlier.
    So, about your two questions:
    No, only the host have to open the game's port, unless if you what to be able to use the host migration system. Indeed, in case of host migration, the system will search a player with is able to host the game, that mean a player who have his port open. And, if you use the dedicated server system, only the server has to open a port.

    That's a question I meet a lot of time, but I cannot really answer to that, since there are theoretically no limit. The limit will come from the host/server computer capacity, and it will also totally depends on your type of game.
     
  21. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, I have send you an email on this address, so can directly answer to my email.
     
  22. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi,

    Can you show me your RPC functions ?
     
  23. DecayGame

    DecayGame

    Joined:
    May 15, 2016
    Posts:
    86
    Hey is this compatible with Realistic FPS Prefab?
     
  24. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hello,
    I don't know, it have not been tested with this asset. Actually, any asset may be compatible with any other if you have a strong level in programming. But it's always quite difficult to make MO (or other multplayer system) work with some FPS assets, since these assets usually don't have a full player prefab with a full body, but only two arms with a gun ! So you have to use an other prefab, and sync it with the "arms prefab" in order to have a full player visible in multiplayer mode.
     
  25. DecayGame

    DecayGame

    Joined:
    May 15, 2016
    Posts:
    86
    ok thanks
     
  26. Legend458

    Legend458

    Joined:
    Mar 13, 2016
    Posts:
    190
    Hello VirtuElle, Is MultiOnline compatible with Unity 5? Also if I made a game and used it with your asset, will it save all the things the player does, for example if I add a building system, and a player builds a base, will it save that information? Thanks.
     
    Last edited: Dec 16, 2016
  27. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, yes, MO works with Unity 5, but it doesn't use the new UI system.
    By default no: if a player build a base, the base will be added on the map, and all the other players will see, but once your player exits the game, his base is destructed: the things are not saved, when a player exits the game, all his "things" are destructed. But if you need to save the "things" in order to be able to use it later, when the player will come back, you can add some fields on the mySQL database, so that you can save some parameter for each players. For each thing you need to save, you can add two fileds. one for the name of the thing (base, factory...), and an other to save the position of it. So that, when a player come back, you can get these data from the database, and re-genered all his things, in the places where it was...
    What type of game dou you want to make exacly ? Maybe if you explain me it a little, I will be able to say you it MO can make it or no ?
     
  28. Legend458

    Legend458

    Joined:
    Mar 13, 2016
    Posts:
    190
    Myself and another developer are planning to make a medieval online game, where there is base building, fighting etc. I am also thinking to have alot of servers with your asset, so does the SQL database make this data automatically if possible? I also want the data to be persistent if the player isn't online, so the base appears to other players still.
     
  29. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Thanks for these precisions. In fact I don't think MO is a good solution for you, since the objects of a player are destroyed once the player exits the game. There are not persistent data. MO is an non-authoritative client server system, and by default the games are hosted by the players themselves. Even if I have added an dedicated server option, the players data are even not persistent, that's managed directly the players, when they exits, there data are destroyed. I think that an authoritative server system would be more adapted for your game, it will be easier to have persistent data with this kind of system.
     
  30. Deleted User

    Deleted User

    Guest

    Is it possible to integrate a new UI of unity 5 of this project? If so, would it be too complicated?
     
  31. Kalle801

    Kalle801

    Joined:
    Mar 3, 2013
    Posts:
    80
    The "MGameParameter" changes always back to Original Settings. How can i stop that please?
     
  32. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Yes, I have spoken about it on the documentation, page 47 :
     
  33. Kalle801

    Kalle801

    Joined:
    Mar 3, 2013
    Posts:
    80
    Would you please update that nice Asset to unity 2017 ?
     
  34. Kalle801

    Kalle801

    Joined:
    Mar 3, 2013
    Posts:
    80
    Why no Updates yet ?
     
  35. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, many thanks for your for your interest in MO.
    In fact I would love make a full update using new Unity Network system, but I currently don't have time to make such an update - since in the case I would probably have to re-code quite all of MO and ML, to integrate all new Unity features from my last update (basically new network system and new GUI)... That's why there was no updates form a pretty long time. I still really hope being able to make it soon...
     
    Kalle801 likes this.
  36. Kalle801

    Kalle801

    Joined:
    Mar 3, 2013
    Posts:
    80
    PLESE do it! I would love to supprt you with a view bugs here and there :)
     
  37. dreamlarp

    dreamlarp

    Joined:
    Apr 22, 2011
    Posts:
    854
    Using UMA2 with your MultiOnline - Multiplayer online kit
    I watched your changing player tutorial but I am still having problems trying to use UMA as my character. Can you please tell me how I can do this or make another tutorial.
     
  38. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hello,
    I am sorry, but the asset has not been tested with UMA. But can you explain your problem, maybe I can help you ?
     
  39. TheCynicalCynic

    TheCynicalCynic

    Joined:
    May 18, 2015
    Posts:
    15
    Hey VirtuElle, I'm looking to possibly picking up the asset but I'm wondering if 2018 messed with MO too much to be that functional without having to fix a lot of the code myself.
    I was also wondering if you'd know how hard it would be to implement this asset:
    https://assetstore.unity.com/packages/tools/modeling/maze-magician-39540

    If it's not too much work for either I'll definitely be picking it up.
     
  40. BrewNCode

    BrewNCode

    Joined:
    Feb 17, 2017
    Posts:
    372
    Hey VirtuElle. We are using your MO kit and we are finding it hard to put the info in the install.php file. I guess you already run into this question. Every time that I want to enter to that file, it just opens me a new tab with the code in it (we are using hostgator) how can we enter to that file? thank you very much.
     
  41. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, thanks for your message. In fact, I have never encounter this problem and I don't really understand it !
    But anyway, it's not very important, since the install.php file is just here to help you to install easily the Mysql tables if you are quite new with webhosting, but in fact you can just do it manually in 2 minutes

    There is only two steps:
    1) open the file Web/functions/logData.php and fill it with the data of your database:

    Code (CSharp):
    1. <?php $logUser = 'your user name'; $logPass = 'your password';$logHost = 'your MySql host';$logDbName = 'your database Name';?>
    Once you have put your data on the blanks, just save the file (and re-upload it on your server).

    2) go on your phpMyAdmin page, click on your database, and import the SQL script which you will find in Web/dataBase.sql" (you just have to click on "import", select the file and let all the default values)

    That's all ;)
     
  42. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Hi, thanks for your interest about MO. That's right that the code is pretty old, but Unity has a good auto upgrade system.

    So, when you import it on Unity 5 you will get a message which ask you if you allow Unity to automatically updrade de scripts, you just have to say Ok "Go ahead", and everyting works fine (you will have some messages on console about deprecated functions, but it work correcty).

    About "Maze Magician"; I don't know this asset, but it should not be a problem to use it with MO since, according about what I saw, it generates some scenes.So, you can easily use these scenes as map for MO, you will just have to add some Spawns gameobject on it. (The way to add a new map is explained on MO doc, it's very easy).
     
  43. BrewNCode

    BrewNCode

    Joined:
    Feb 17, 2017
    Posts:
    372
    Hello Virtuelle. I was wandering, how can I link MO kit with the UMA, so all players can see the same character in their copmputers? if you have some tutorials about it?
     
  44. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    I am sorry, but the asset has not been tested with UMA. But you can read the documation about how change player, and watch the change player tutorial, it my help you (even if it's not with UMA, it shows the process to follow)
     
  45. BrewNCode

    BrewNCode

    Joined:
    Feb 17, 2017
    Posts:
    372
    So you don't know how to sync the data to all clients? mmm...
     
  46. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    I just told the asset has not been tested with UMA since you asked about it, but about data sync, you just have to use RPC functions. You can watch the change player tutorial it explains all of that :
     
  47. BrewNCode

    BrewNCode

    Joined:
    Feb 17, 2017
    Posts:
    372
    Thanks for the video, VirtuElle. Say, is there a way to do the data sync in C#?
     
  48. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    The tutorial, the asset and all the doc in in C#, so I don't really understand what you mean.
     
  49. tkaczu

    tkaczu

    Joined:
    Aug 8, 2013
    Posts:
    6
    Hi I have a problem. I am doing everything like your video shows and I cant build it. There is many compile errors.
     
  50. VirtuElle

    VirtuElle

    Joined:
    Jan 27, 2013
    Posts:
    458
    Thanks for your message, I have direcly send you a private message