Not able to update all the users' set of cards on the network.

Options
Hi! I have been stuck on this for a while now and not getting any solution over the internet.
I want to show set of 3 cards as Text on the user's screen whenever the host(master client) hits Start button(which is only visible to the master client). The problem is my RPC function is not working , in the console it says "Write failed. Custom type not found. Systems.Collections.GenericList".Please look for the Case 2 only in switch loop as i have written for 2 players only as of now. My code is -

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine.UI;
public class CardDistribution : MonoBehaviourPun
{
private Dictionary<string, List<int>> deckofCards;
int n_hearts = 13;
int n_clubs = 13;
int n_spades = 13;
int n_diamonds = 13;

[SerializeField]
private Text cardsGotText;
List<int> currentPlayerSetOfcards = new List<int>();

private PhotonView PV;

//Had to declare once and for all here because in the block it initializes everytime it is called and is most likely to give the same values again and again
System.Random rand = new System.Random();

void Start()
{
//Creating deck of cards;
deckofCards = new Dictionary<string, List<int>>()
{
{ "Hearts", new List<int>{1,2,3,4,5,6,7,8,9,10,11,12,13 } } ,
{ "Clubs", new List<int>{1,2,3,4,5,6,7,8,9,10,11,12,13 } } ,
{ "Spades", new List<int>{1,2,3,4,5,6,7,8,9,10,11,12,13 } } ,
{ "Diamonds", new List<int>{1,2,3,4,5,6,7,8,9,10,11,12,13 } }
};

PV = this.GetComponent<PhotonView>();

}

public void OnStartButtonClick()
{
int numberOfPlayers = PhotonNetwork.CurrentRoom.PlayerCount;
List<int> firstPlayer2v2 = new List<int>();
List<int> secondPlayer2v2 = new List<int>();

switch (numberOfPlayers)
{

case 2:
firstPlayer2v2 = RandomDistributor(firstPlayer2v2);
secondPlayer2v2 = RandomDistributor(secondPlayer2v2);

break;

default:
break;
}

if(PV.IsMine)
PV.RPC("RPC_function", RpcTarget.All, true, firstPlayer2v2, secondPlayer2v2);
}

[PunRPC]
public void RPC_function(bool update, List<int>firstPlayer2v2, List<int>secondPlayer2v2)
{
if (update)
{
if (PhotonNetwork.LocalPlayer.ActorNumber == 1)
{
currentPlayerSetOfcards = firstPlayer2v2;
string cardsTodisp = "";
foreach (int i in currentPlayerSetOfcards)
cardsTodisp = cardsTodisp + " " + i.ToString();
cardsGotText.text = cardsTodisp;
}
else if (PhotonNetwork.LocalPlayer.ActorNumber == 2)
{
currentPlayerSetOfcards = secondPlayer2v2;
string cardsTodisp = "";
foreach (int i in currentPlayerSetOfcards)
cardsTodisp = cardsTodisp + " " + i.ToString();
cardsGotText.text = cardsTodisp;
}
update = false;
}
}


#region TeenPattiDistributor
private List<int> RandomDistributor(List<int>groupOfThreeCards)
{
string RandKey; // To generate random suits

for (int i = 0; i < 3; i++)
{
List<string> keysList = new List<string>(deckofCards.Keys); //Collecting the availabel keys(suits) from the deckofCards dictionary

RandKey = keysList[rand.Next(4)];
int randomCardNumber = -1;

switch (RandKey)
{
case "Hearts":
randomCardNumber = rand.Next(n_hearts); //To pick a card from the generated random suit
n_hearts -= 1;
break;
case "Clubs":
randomCardNumber = rand.Next(n_clubs);
n_clubs -= 1;
break;
case "Spades":
randomCardNumber = rand.Next(n_spades);
n_spades -= 1;
break;
case "Diamonds":
randomCardNumber = rand.Next(n_diamonds);
n_diamonds -= 1;
break;
default:
break;
}

List<int> temp = new List<int>(deckofCards[RandKey]); //Copying the selected list into a temp list

groupOfThreeCards.Add(temp[randomCardNumber]);
//Debug.Log(RandKey + " " + temp[randomCardNumber]);
temp.RemoveAt(randomCardNumber);
deckofCards[RandKey] = temp; //Copying into the original list
// prevRandKey = RandKey;
}
return groupOfThreeCards;
}
#endregion
}

Answers

  • S_Oliver
    S_Oliver ✭✭✭
    edited April 2020
    Options
    You trying to send a List<int> via an RPC which is not supported.
    Eiter you add it https://doc.photonengine.com/en-US/realtime/current/reference/serialization-in-photon
    to the custom types so you can use it or thinking of an different way.

    You could cast your list to an object an cast it after receiving back to a List<int>.
    Im not sure if this is working but a simple try^^ worth it.
  • BigGameCo
    Options
    photon can only send certain data types by default.

    https://doc.photonengine.com/en-US/realtime/current/reference/serialization-in-photon

    for other data types - eg lists - you need to tell photon how to handle it. Here's some code I used a while back to send Lists over photon. You would change your functions to receive byte arrays instead of lists
    public byte[] ListToByteArray(List<int> frameOfData){
    		BinaryFormatter bf = new BinaryFormatter();
    		MemoryStream ms = new MemoryStream();
    		bf.Serialize(ms, frameOfData);
    		byte[] myByteArray = ms.ToArray();
    		return myByteArray;
    	}
    	public List<int> ByteArrayToList(byte[] dataBytes){
    		MemoryStream memStream = new MemoryStream();
    		BinaryFormatter binForm = new BinaryFormatter();
    		memStream.Write(decompressed, 0, dataBytes.Length);
    		memStream.Seek(0, SeekOrigin.Begin);
    		List<int> dataObject = (List<int>) binForm.Deserialize(memStream);
    		return dataObject;
    	}