Hi everybody,
I’m trying to create a multiplayers game for fun. But I have a little problem with OnPhotonSerializeView() and/or the viewID (i don’t know the real cause of my issue).
In short, when you join a room, you are not in the game yet. There is a list of players split in 2 teams. Here is the problem :
- if the “master” creates the room and begins to play, and another player joins the game later, only the first one sees the other moves.
- but if the 2 players enter the game together, they see each other moving… Strange…
Now, how i tried to do that :
in the room, if you are the master, you start the game by opening the map and sending a rpc to the ready players to join.
When a player joins the game, he sends a buffered rpc in order to :
- spawn in the map for each player in game
- add his name in a list of players in game that all the players hold (and when a player joins the others, he knows who he has to spawn in his map)
so, the code to spawn (in short) followed by the script to synchronize the movement :
`
public void SpawnOnNetwork ()
{
photonView.RPC("NewPlayer", PhotonTargets.AllBuffered, PhotonNetwork.player, PhotonNetwork.AllocateViewID());
}
[RPC] void NewPlayer (PhotonPlayer p, int id)
{
// If i'm inGame => spawn the player
if ((State)PhotonNetwork.player.customProperties["s"] == State.inGame)
StartCoroutine(SpawnPlayer(p, id));
Add (p, id); // List<Player> avec Player = (PhotonPlayer , int)
}
IEnumerator SpawnPlayer (PhotonPlayer p, int id)
{
Transform newPlayer = Instantiate(player, Vector3.zero, player.transform.rotation) as Transform;
newPlayer.GetComponent<PhotonView>().viewID = id;
if (p.isLocal) {
newPlayer.name = "MyPlayer";
newPlayer.position = new Vector3 (Random.Range(0.5f,1.5f), 1.5f, Random.Range(0.5f,1.5f));
ActivePlayer (newPlayer); // set scripts to control the player
}
else {
newPlayer.name = "OtherPlayer";
yield return StartCoroutine(AskPosition(p)); // get the position of the player
Player_Controller pc = newPlayer.GetComponent<Player_Controller>() as Player_Controller;
pc.startPos = lastOtherPlayerPos;
pc.endPos = lastOtherPlayerPos;
lastOtherPlayerPos = Vector3.zero;
}
}
IEnumerator AskPosition (PhotonPlayer p)
{
photonView.RPC("Give", p, PhotonNetwork.player);
while (lastOtherPlayerPos.Equals(Vector3.zero))
yield return null;
}
[RPC] void Give (PhotonPlayer p)
{
photonView.RPC("Receive", p, GameObject.Find("MyPlayer").transform.position);
}
[RPC] void Receive (Vector3 position)
{
lastOtherPlayerPos = position;
}
public void SpawnPlayers ()
{
foreach (Player p in playersInGame)
StartCoroutine(SpawnPlayer (p.p, p.id));
}
public class Player_Controller : Photon.MonoBehaviour {
...
public Vector3 startPos;
public Vector3 endPos;
...
void Update ()
{
if (photonView.isMine)
{
// control of the player
}
else
{
SyncedMovement();
}
}
void SyncedMovement()
{
...
syncTime += Time.deltaTime;
transform.position = Vector3.Lerp(startPos, endPos, syncTime / syncDelay);
transform.rotation = Quaternion.Lerp(startRot, endRot, syncTime / syncDelay);
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
...
}
else
{
endPos = (Vector3)stream.ReceiveNext();
startPos = transform.position;
endRot = (Quaternion)stream.ReceiveNext();
startRot = transform.rotation;
...
syncTime = 0f;
syncDelay = Time.time - lastSyncTime;
lastSyncTime = Time.time;
}
}
}
`
last time, i had a alert in unity console about it : “Received OnSerialization for view ID 1001. We have no such PhotonView!” but i don’t know where it comes from…
if you have a solution, or a better idea to do sth similar, i’m interested !!!
Thanks a lot for your time !!!
Antoine
ps: sorry for any language mistakes…