MPSK Matchmaking Lobby and MySQL Login System

1235»

Comments

  • Neuron Posts: 249Member, MPTester
    edited May 26

    That is a fun video! Did you do the voice? lol!!

    Those are just for prototyping. I borrowed those voices from L4D.
    https://en.wikipedia.org/wiki/Chad_Coleman
  • JoseJose Posts: 16Member
    Neuron, you're great!, I modified the vp_MPMaster script and it did work!, but still, i think I'm doing something wrong because it only works in the editor, and not in the build, strange huh!, these are the changes I made:

    // Added variables to spawn different player types
    public int currentPlayerType;
    public string[] playerTypeStrings;

    [PunRPC]
    public void RequestInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    if (!PhotonNetwork.isMasterClient)
    return;

    // make every joining player load the current level
    TransmitLoadLevel(player, CurrentLevel);

    if (PhotonNetwork.room.PlayerCount > 1)
    {
    // for non-masters we send spawn info straight away. this assumes
    // the master has already loaded the level and knows the spawnpoints
    TransmitInitialSpawnInfo(player, id, name);
    }
    else
    {
    // if we're the FIRST player in the game we take over the game, but
    // we must wait sending spawn info to ourself until 'OnLevelLoad'
    // triggers (because there are no spawnpoints yet)
    m_TookOverGame = true;
    }

    }


    /// <summary>
    ///
    /// </summary>
    public void TransmitInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    // allocate team number, player type and spawnpoint
    int teamNumber = 0;
    string playerTypeName = null;
    vp_Placement placement = null;
    currentPlayerType = PlayerPrefs.GetInt("SelectedCharacter"); // Added this line to spawn different player types

    if (vp_MPTeamManager.Exists)
    {
    teamNumber = ((vp_MPTeamManager.Instance.Teams.Count <= 1) ? 0 : vp_MPTeamManager.Instance.GetSmallestTeam());
    playerTypeName = vp_MPTeamManager.Instance.GetTeamPlayerTypeName(teamNumber);
    placement = vp_MPPlayerSpawner.GetRandomPlacement(vp_MPTeamManager.GetTeamName(teamNumber));
    }

    if (placement == null)
    placement = vp_MPPlayerSpawner.GetRandomPlacement();

    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }
    Any ideas what went wrong? Would you mind to share how you did it?
    Thank you,
    Jose.
  • Neuron Posts: 249Member, MPTester
    edited June 2
    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }


    I removed this completely, as it would randomly set the defaultplayertype on connections with a high ping and set the playerTypeName explicitly from the actorSelection.

    But... I also have all players join as a bot before joining as a unique player and moved the actorSelection into the game scene after the player joins as a spectator so Photon would be able to propagate whether that player was already taken since Photon does not support getting player info from rooms or inside lobby unless you have joined said room first, so maybe setting the Hash after the scene loads is the key.

    p.s. I wouldn't use PlayerPrefs on MP as it's very unreliable and insecure. You could write to a bytes file or even serialization like a SaveLoad method that saves the info to the users persistentdata or documents.

    Something like


    public enum STORAGETYPE { BINARY, JSON, XML }
    [Header("Storage Method")]
    public STORAGETYPE storageType = STORAGETYPE.BINARY;

    public enum DIRECTORY { PERSISTENTDATAPATH, DOCUMENTS, MYGAMES }
    [Header("Save Path, DOCUMENTS and MYGAMES for Windows Only")]
    public DIRECTORY directoryPath = DIRECTORY.PERSISTENTDATAPATH;

    void Start()
    {
    if (directoryPath == DIRECTORY.PERSISTENTDATAPATH) directory = Application.persistentDataPath;
    else if (directoryPath == DIRECTORY.DOCUMENTS) directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace("\\", "/") + Path.DirectorySeparatorChar + Application.companyName + Path.DirectorySeparatorChar + Application.productName;
    else if (directoryPath == DIRECTORY.MYGAMES) directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).Replace("\\", "/") + Path.DirectorySeparatorChar + "My Games" + Path.DirectorySeparatorChar + Application.companyName + Path.DirectorySeparatorChar + Application.productName;
    if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
    }

    public void UpdateUser()
    {
    if (File.Exists(directory + Path.DirectorySeparatorChar + "userdata.dat"))
    {
    //Overwrite file
    return;
    }
    Save("userdata.dat");
    }

    void Save(string filename)
    {
    PlayerData playerData = new PlayerData();

    playerData.selectedPlayer = playerType;
    playerData.teamNumber = teamNumber;
    }

    if (storageType == STORAGETYPE.BINARY)
    {
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    FileStream fileStream = File.Open(directory + Path.DirectorySeparatorChar + filename, FileMode.OpenOrCreate, FileAccess.Write);

    binaryFormatter.Serialize(fileStream, playerData);
    fileStream.Close();
    fileStream.Dispose();
    }

    else if (storageType == STORAGETYPE.JSON)
    {
    string file = directory + Path.DirectorySeparatorChar + filename;
    string data = JsonUtility.ToJson(playerData, true);
    File.WriteAllText(file, data);
    }

    else if (storageType == STORAGETYPE.XML)
    {
    string file = directory + Path.DirectorySeparatorChar + filename;
    XmlSerializer data = new XmlSerializer(typeof(PlayerData));
    using (FileStream fileStream = new FileStream(file, FileMode.Create, FileAccess.Write))
    {
    data.Serialize(fileStream, playerData);

    fileStream.Close();
    fileStream.Dispose();
    }
    }

    [Serializable]
    public class PlayerData
    {
    public string playerType;
    public int teamNumber;
    }

    this will save all the userdata safely and reliabily in BINARY, JSON, or XML but Unity supports all three formats of serialization. JSON is the fastest for large amounts of data but if its just two strings it doesn't matter.

    Then, when the scene loads, we call the load functions to the Photon Hash tables something like:

    public void TryLoad()
    {
    if (!File.Exists(directory + Path.DirectorySeparatorChar + "userdata.dat"))
    {
    gm.MessageText("File doesn't exist...", Color.red, 3, 30, TextAnchor.UpperLeft);
    return;
    }
    PopulateList();
    }

    public void PopulateList()
    {
    datList.Clear();
    datList.TrimExcess();

    DirectoryInfo dir = new DirectoryInfo(directory);
    FileInfo[] info = dir.GetFiles("*.dat");
    foreach (FileInfo f in info) datList.Add(f);

    Load(fileName);
    }

    void Load(string fileName)
    {
    PlayerData data2 = new PlayerData();

    if (storageType == STORAGETYPE.BINARY)
    {
    BinaryFormatter bf2 = new BinaryFormatter();
    FileStream file2 = File.Open(directory + Path.DirectorySeparatorChar + fileName, FileMode.Open, FileAccess.Read);
    data2 = (PlayerData)bf2.Deserialize(file2);
    file2.Close();
    file2.Dispose();
    }

    else if (storageType == STORAGETYPE.JSON)
    {
    string file = directory + Path.DirectorySeparatorChar + fileName;
    string serializedData = File.ReadAllText(file);
    data2 = JsonUtility.FromJson<PlayerData>(serializedData);
    }

    else if (storageType == STORAGETYPE.XML)
    {
    string file = directory + Path.DirectorySeparatorChar + fileName;
    using (FileStream stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    XmlSerializer serializer = new XmlSerializer(typeof(PlayerData));
    data2 = (PlayerData)serializer.Deserialize(stream);

    stream.Close();
    stream.Dispose();
    }
    }

    playerType = data2.playerType;
    teamNumber = data2.teamNumber;
    }



    and from there you just set the UFPS playerTypeName as userdat.playerType and UFPS teamNumber as userdata.teamNumber.

    It may not be as easy as PlayerPrefs, but in the long run you'll be better off.

    Also, you can set all playerInfo in vp_Gameplay as its a static class and can be extended or edited to include your prefs.
  • Neuron Posts: 249Member, MPTester
    edited June 2
    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }


    It is possible that playerTypeName is being stored in PlayerPrefs so it's not null or empty when you build, but that's just a guess.
    if (string.IsNullOrEmpty(playerTypeName))

    try clearing your prefs by running this once.

    void Start()
    {
    PlayerPrefs.DeleteAll();
    }

    I would also say make sure playerTypeName = playerTypeStrings[currentPlayerType]; matches the name of the playerType asset, but if that was the case it wouldn't work in editro either.
  • JoseJose Posts: 16Member
    edited June 20
    Well, it took me a while but finally did it, I removed the part like you said, and also changed the PlayerPrefs for the characterType and BOOM!! it worked!!, thank you for all the help Neuron I really appreciated. I didn't do the part of saving player data yet, it could take me a while to do it, although I'm looking forward to it since is better implementation that the one I already have.
  • WeendieGamesWeendieGames Posts: 42Member
    Jose said:

    Well, it took me a while but finally did it, I removed the part like you said, and also changed the PlayerPrefs for the characterType and BOOM!! it worked!!, thank you for all the help Neuron I really appreciated. I didn't do the part of saving player data yet, it could take me a while to do it, although I'm looking forward to it since is better implementation that the one I already have.


    Hi Jose, did you keept the changes on the vp_MPPlayerSpawner.cs? Or only in the vp_MPMaster.cs ?

    i'm still trying to figure out how to use the actor selection properly
  • JoseJose Posts: 16Member
    Hi WeendieGames,

    I removed all the changes made in the vp_MPPlayerSpawner.cs script, and instead I made the changes in the vp_MPMaster.cs just like Neuron said, I did this because it was not working for me in the build, only in the editos, like I said before, but your case might be different, I have to say that it has been really hard for me to work on multiplayer, right now I'm having errors all over the place, if I disconnect and come back to the room I get a spawn error, sometimes out of nothing I get crashes about InitShooters, SpawnProjectiles, TimerEvents and so on lol, anyways I hope making the changes in the vp_MPMaster.cs does the trick for you
  • cristopherloncristopherlon Posts: 108Member
    edited July 21
    help thisss, pleasee

    http://forum.photonengine.com/discussion/10072/photon-enemies-scene-global#latest

    According to users, it's a loadscene problem, but I've tried:



    mt_Connection(M-Theory).cs:

    OnJoinedRoom:

    PhotonNetwork.LoadLevel(Lobby.mapList[Lobby.SelectedMap]);

    and I tried:

    mt_MPConnection(UFPS).cs:

    OnJoinedRoom:

    PhotonNetwork.LoadLevel("TestGame");

    but nothing change

  • cristopherloncristopherlon Posts: 108Member
    edited July 22
  • cristopherloncristopherlon Posts: 108Member
    edited July 23
    Jose said:

    Neuron, you're great!, I modified the vp_MPMaster script and it did work!, but still, i think I'm doing something wrong because it only works in the editor, and not in the build, strange huh!, these are the changes I made:


    // Added variables to spawn different player types
    public int currentPlayerType;
    public string[] playerTypeStrings;

    [PunRPC]
    public void RequestInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    if (!PhotonNetwork.isMasterClient)
    return;

    // make every joining player load the current level
    TransmitLoadLevel(player, CurrentLevel);

    if (PhotonNetwork.room.PlayerCount > 1)
    {
    // for non-masters we send spawn info straight away. this assumes
    // the master has already loaded the level and knows the spawnpoints
    TransmitInitialSpawnInfo(player, id, name);
    }
    else
    {
    // if we're the FIRST player in the game we take over the game, but
    // we must wait sending spawn info to ourself until 'OnLevelLoad'
    // triggers (because there are no spawnpoints yet)
    m_TookOverGame = true;
    }

    }


    /// <summary>
    ///
    /// </summary>
    public void TransmitInitialSpawnInfo(PhotonPlayer player, int id, string name)
    {

    // allocate team number, player type and spawnpoint
    int teamNumber = 0;
    string playerTypeName = null;
    vp_Placement placement = null;
    currentPlayerType = PlayerPrefs.GetInt("SelectedCharacter"); // Added this line to spawn different player types

    if (vp_MPTeamManager.Exists)
    {
    teamNumber = ((vp_MPTeamManager.Instance.Teams.Count <= 1) ? 0 : vp_MPTeamManager.Instance.GetSmallestTeam());
    playerTypeName = vp_MPTeamManager.Instance.GetTeamPlayerTypeName(teamNumber);
    placement = vp_MPPlayerSpawner.GetRandomPlacement(vp_MPTeamManager.GetTeamName(teamNumber));
    }

    if (placement == null)
    placement = vp_MPPlayerSpawner.GetRandomPlacement();

    if (string.IsNullOrEmpty(playerTypeName))
    {
    vp_MPPlayerType playerType = vp_MPPlayerSpawner.GetDefaultPlayerType();
    if (playerType != null)
    playerTypeName = playerTypeStrings[currentPlayerType]; // Changed playerType.name to playerTypeStrings[currentPlayerType]; to spawn different player types
    else
    Debug.LogError("Error (" + this + ") Failed to assign PlayerType to player " + id.ToString() + ". Make sure player types are assigned in your vp_MPPlayerSpawner and vp_MPMaster components.");

    }
    Any ideas what went wrong? Would you mind to share how you did it?
    Thank you,
    Jose.
    result this error:

    image
    (https://uploaddeimagens.com.br/images/001/006/233/full/dawd.png?1500791044)
  • JoseJose Posts: 16Member
    edited August 7
    Try this to fix the spawn point


    public static vp_Placement GetRandomPlacement(float physicsCheckRadius, string tag)
    {

    // abort if scene contains no spawnpoints
    if((SpawnPoints == null) || (SpawnPoints.Count < 1))
    return null;

    // fetch a random spawnpoint
    vp_SpawnPoint spawnPoint = null;
    if (string.IsNullOrEmpty(tag))
    spawnPoint = GetRandomSpawnPoint();
    else
    {
    spawnPoint = GetRandomSpawnPoint(tag);
    if (spawnPoint == null)
    {
    spawnPoint = GetRandomSpawnPoint();
    Debug.LogWarning("Warning (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint tagged '" + tag + "'. Falling back to 'any random spawnpoint'.");
    }
    }

    //Debug.Log("Spawnpoints length: " + SpawnPoints.Count); // Fixing SpawnPoint error in multiplayer
    // if no spawnpoint was found, revert to world origin
    if (spawnPoint == null)
    {
    /*
    Debug.LogError("Error (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint" + (!string.IsNullOrEmpty(tag) ? (" tagged '" + tag + "'") : ".") + " Reverting to world origin.");
    return null; */ // Original UFPS Code

    // Changed to this to fix spawn point error
    //Debug.Log("Error (vp_SpawnPoint --> GetRandomPlacement) Could not find a spawnpoint" + (!string.IsNullOrEmpty(tag) ? (" tagged '" + tag + "'") : ".") + " Reverting to world origin.");
    spawnPoint = FindObjectOfType<vp_SpawnPoint>();
    }

    // /* Added while fixing spawn point error
    if (spawnPoint == null)
    {
    Debug.LogError("cant find any spawnpoints");
    return null;
    }
    // */

    // found a spawnpoint! use it to create a placement
    return spawnPoint.GetPlacement(physicsCheckRadius);

    }


    Basically I just commented the errors and instead added this
    spawnPoint = FindObjectOfType<vp_SpawnPoint>();

    to try to find a spawn point again, I think that's how you can fix it, about the other errors I have no idea, good look with everything, I hope that helps!
  • redhawkredhawk Posts: 489Member, MPTester
    @Neuron spawning as bots first, wow that's cool. You are like the master at multiplayer. That is exactly how I want to do my game where when the player starts their game, they spawn in and they play like it's single player with bots and others can join then or leave whenever.
  • volfase Posts: 3Member
    news menus what work with newest ufps
Sign In or Register to comment.