Simple read write & RPC logic error

Options
I have tried two varying ways to go about telling the other player in the scene that i am ready and vice versa yet it does not seem to take. What seems to be happening is that the master client will tell the other client it is ready but the client will never tell the master client it is ready.

i have tried it through an RPC
[RPC]
public void SelectionFinished(int photonViewID)
{
	PhotonView pv = PhotonView.Find(photonViewID);

	if(pv == null)Debug.LogError("photon view is null");

	if(pv.isMine)
	{
		hasFinishedSelection = true;
		Debug.Log("i have finished");
	}
	else
	{
		opponentHasFinishedSelection = true;
		Debug.Log("opponent has finished");
	}
}

and this way
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
	if(stream.isWriting)
	{
		stream.SendNext(hasFinishedSelection);
	}
	else
	{
		opponentHasFinishedSelection = (bool)stream.ReceiveNext();
	}
}

but each time it only the master client seems to write out that it has finished but the client never does so.

EDIT: I would like to add, because i think this may be the reason for this issue...is that the gameObject with the photonView script containing this logic is not instantiated using photon.instantiate...Is this perhaps causing viewID's to conflict?

UPDATE: I created some prefabs to instantiate via photon as my suspicion that the viewID's were conflicting were probably right. However the above code still would not work...Perhaps i have having trouble understanding how Photon works but here is the class.
public class WCSelectionPhoton : Photon.MonoBehaviour 
{
	public bool hasFinishedSelection;
	bool opponentHasFinishedSelection;

	public WCSelectionOnlineState selectionState;

	// Use this for initialization
	void Start () 
	{
		hasFinishedSelection = false;
		opponentHasFinishedSelection = false;
	}
	
	// Update is called once per frame
	void Update () 
	{
		if(photonView.isMine)
		{
			Debug.Log("I am ready:"+hasFinishedSelection);
			Debug.Log("opponent ready:"+opponentHasFinishedSelection);
			if(hasFinishedSelection && opponentHasFinishedSelection)
			{
				hasFinishedSelection = opponentHasFinishedSelection = false;

				selectionState.Go();
			}
		}
	}

	public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
	{
		if(stream.isWriting)
		{
			stream.SendNext(hasFinishedSelection);
		}
		else
		{
			opponentHasFinishedSelection = (bool)stream.ReceiveNext();
		}
	}
}

how it works is a local WCSelectionOnlineState object selectionState sets the local copy of hasFinishedSelection to true on a button event(Code below). And as far as i am aware each WCSelectionPhoton in the scene should write to each other No? I previously had debug messages inside the OnPhotonSerializeView and it seemed as if it was reading and writing...but obviously i do not know which one it is for. But for some reason for both instances of WCSelectionPhoton even though they had both sent true into the stream of OnPhotonSerializeView, opponentHasFinishedSelection was always false for both in the update...what is happening?

For completeness here is the WCSelectionOnlineState class which exists in the editor and is not instantiated via PhotonNetwork.Instantiate and has a PhotonView component.
public class WCSelectionOnlineState : WCSelectionState
{
	public GameObject SelectionPhotonViewPrefab;

	PhotonView _photonView;

	WCSelectionPhoton selectionPhoton;
	
	void Awake ()
	{
		_photonView = GetComponent<PhotonView>();
	}

	// Use this for initialization
	void Start ()
	{
		StartSelection();
	}

	 void StartSelection()
	{
		GameObject gObj = PhotonNetwork.Instantiate("Prefabs/"+SelectionPhotonViewPrefab.name,Vector3.up*5, Quaternion.identity,0);

		selectionPhoton = gObj.GetComponent<WCSelectionPhoton>();
		selectionPhoton.selectionState = this;

		_photonView.RPC("init",PhotonTargets.AllBufferedViaServer,gObj.GetComponent<PhotonView>().viewID);
	}

	[RPC]
	public void init( int viewID )
	{
		PhotonView pv = PhotonView.Find(viewID);

		pv.transform.parent = transform;
		NGUITools.MarkParentAsChanged (pv.gameObject);
		
		pv.transform.localScale = new Vector3(1,1,1);
		pv.transform.localPosition = Vector3.zero;
	}
	
	// Update is called once per frame
	void Update () 
	{

	}
	
	void OnEnable ()
	{
		WCSelectionGoButton.onSelectionGoPressed += HandleonSelectionGoPressed;
	}

	void OnDisable ()
	{
		WCSelectionGoButton.onSelectionGoPressed -= HandleonSelectionGoPressed;
	}

	void HandleonSelectionGoPressed (bool isPressed)
	{
		message.SetMainLabelText("Waiting For Opponent");
		message.gameObject.SetActive(true);
		message.dismissalButton.SetActive(false);

            //Should be synchronized across both instances yes?
		selectionPhoton.hasFinishedSelection = true;
	}

   //This never gets called for some reason...
	public void Go()
	{
		WCStateManager stateManager = WCStateManager.instance;
		stateManager.SetState(stateManager.gameManager.PlayingState);
	}
}

Comments

  • Tobias
    Options
    Using OnPhotonSerializeView to sync a property that changes rarely is a bit wasteful.

    You should use a Player Custom Property to store something like that. Use PhotonNetwork.player.SetCustomProperties() and set a "rdy" prop.
    You can re-set it to false when you started the round/game.
  • Thanks for the suggestion, it seems to make much more sense and i agree sounds like a waste, and i will probably change it posthaste. My Beef with it is not that it's wasteful...but the fact that it does not seem to work...Any idea why? or more than likely i am doing it very wrong.