Search code examples
c#unity-game-enginenetworkingphoton

Syncing Text using PUN in Unity


I'm making a simple Word Builder type of game (where one player enters a word, and the other player enters a word starting with the last letter of the first player's word), and I can't get the Text to show up on both the screens. I'm able to get the text to show up if I hard code it, like:

    [PunRPC]
    public void DisplayWord ()
    {
        MainWord.text = "Word";
    }

But I can't get it to display the word a player just entered to both screens, I thought this code would word:

    [PunRPC]
    public void DisplayWord ()
    {
        MainWord.text = UsedString;
        //UsedString is the word the (one of the) players just entered.
    }

Any help would be greatly appreciated, thank you so much!

Here's the full code for entering a word:

using System.Collections.Generic;
using UnityEngine.UI;
using UnityEngine;
using Photon.Pun;

public class DictionaryScript : MonoBehaviourPunCallbacks
{
    List<string> DictA = new List<string> () { 
    "a",
    "aa",
    "aaa",
    "aah",
    "aahed",
    "aahing",
    "aahs",
    "aal",
    "aalii",
    "aaliis",
    "aals",
    "aam",
    "aani",
    "aardvark",
    "aardvarks",
    "aardwolf",
    "aardwolves",
    "aargh",
    "aaron",
    "aaronic",
    "aaronical",
    "aaronite",
    "aaronitic",
    "aarrgh",
    "aarrghh",
    "aaru",
    "aas",
    "aasvogel",
    "aasvogels"};

    public List<string> DictAUsed = new List<string>() { };

    public string UsedString;
    public string NewString;

    public InputField inputField;
    public Text AddedWord;
    public Text MainWord;
    public Text TurnText;

    public Text ConnectedText;
    public Button StartButton;
    public Canvas OverlayCanvas;

    // Start is called before the first frame update
    public void Awake()
    {
        if (PhotonNetwork.IsMasterClient)
        {
            StartButton.enabled = true;
            OverlayCanvas.enabled = true;
        }
        else
        {
            StartButton.enabled = false;
            OverlayCanvas.enabled = true;
        }
    }

    void Start()
    {
        if (PhotonNetwork.InRoom)
        {
            ConnectedText.text = "Connected!";
        }
    }

    public void StartGame ()
    {
        photonView.RPC("CanvasDisplay", RpcTarget.All);
    }

    public void MyWord (string newWord)
    {
        string newString = newWord.ToLower();
        print(newString);

        if (DictA.Contains(newString) && newString[0] == MainWord.text[0] && !DictAUsed.Contains(newString))
        {
            
            UsedString = newString;
            Debug.Log(UsedString);
            photonView.RPC("OnInput", RpcTarget.All);
        }

        else
        {
            print("This word does not exist!");
            AddedWord.text = newString + " is not a valid word!";
        }

        inputField.text = "";
    }


    [PunRPC]
    public void OnInput ()
    {
        DictAUsed.Add(UsedString);
        AddedWord.text = "The word was: " + UsedString;
        photonView.RPC("DisplayWord", RpcTarget.All);
    }

    [PunRPC]
    public void DisplayWord ()
    {
        MainWord.text = UsedString;
        //UsedString is the word the (one of the) players just entered.
    }

    [PunRPC]
    public void CanvasDisplay()
    {
        //string Alphabet = "abcdefghijklmnopqrstuvwxyz";
        string Alphabet = "aaaaaaaaaaaaaaaaaaaaaaaaaa";
        MainWord.text = Alphabet[Random.Range(0, 25)].ToString();
        StartButton.enabled = false;
        OverlayCanvas.enabled = false;
    }
}

I only have words starting with 'aa' for now, I'll add all the words once I can get it working.


Solution

  • UsedString is not synchronized in your network => Each player might have a different value for UsedWorld at the moment the RPC get called.

    Why not pass on the UsedWord as argument to OnInput and DisplayWord?

    Also why is DisplayWord even called via RPC at all? Since OnInput is alreay synchronized to ALL you could simply call the method right away

    ...
        photonView.RPC(nameof(OnInput), RpcTarget.All, UsedWord);
    ...
    
    [PunRPC]
    public void OnInput (string usedString)
    {
        DictAUsed.Add(usedString);
        AddedWord.text = "The word was: " + usedString;
    
        // since this shall happen on any client as well
        // why even call it via RPC?
        // OnInput is called on ALL anyway so just do it right away
        DisplayWord(usedString);
    }
    
    public void DisplayWord (string usedString)
    {
        MainWord.text = usedString;
    }