- Home /
Photon Unity Networking (Viking Demo) Error: Argument is out of range.
I'm developing a MMO. I'm using for networking Photon Viking Demo. In this demo only position, rotation, rigidbody and walk/run animations are synchronized (for players. I'm trying to make synchronized attack or jump animations. I did simple changes on "ThirdPersonNetworkVik.cs". Here is the original codes of "ThirdPersonNetworkVik.cs":
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
//We own this player: send the others our data
// stream.SendNext((int)controllerScript._characterState);
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(rigidbody.velocity);
}
else
{
//Network player, receive data
//controllerScript._characterState = (CharacterState)(int)stream.ReceiveNext();
correctPlayerPos = (Vector3)stream.ReceiveNext();
correctPlayerRot = (Quaternion)stream.ReceiveNext();
rigidbody.velocity = (Vector3)stream.ReceiveNext();
}
}
private Vector3 correctPlayerPos = Vector3.zero; //We lerp towards this
private Quaternion correctPlayerRot = Quaternion.identity; //We lerp towards this
void Update()
{
if (!photonView.isMine)
{
//Update remote player (smooth this, this looks good, at the cost of some accuracy)
transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * 5);
transform.rotation = Quaternion.Lerp(transform.rotation, correctPlayerRot, Time.deltaTime * 5);
}
}
And these codes edited by me for open a stream and send LeftControl key if pressed LeftControl button and update the other player and play the animation. Edited script "ThirdPersonNetworkVik.cs" >> link text
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
//We own this player: send the others our data
// stream.SendNext((int)controllerScript._characterState);
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(rigidbody.velocity);
//ADDED CODE BLOCK
if (Input.GetKeyDown(KeyCode.LeftControl))
{
stream.SendNext(KeyCode.LeftControl);
}//ADDED CODE BLOCK
}
else
{
//Network player, receive data
//controllerScript._characterState = (CharacterState)(int)stream.ReceiveNext();
correctPlayerPos = (Vector3)stream.ReceiveNext();
correctPlayerRot = (Quaternion)stream.ReceiveNext();
rigidbody.velocity = (Vector3)stream.ReceiveNext();
//ADDED CODE BLOCK
keycode55 = (KeyCode)stream.ReceiveNext();
//ADDED CODE BLOCK
}
}
private Vector3 correctPlayerPos = Vector3.zero; //We lerp towards this
private Quaternion correctPlayerRot = Quaternion.identity; //We lerp towards this
//ADDED CODE BLOCK
private KeyCode keycode55 = KeyCode.None;
//ADDED CODE BLOCK
void Update()
{
if (!photonView.isMine)
{
//Update remote player (smooth this, this looks good, at the cost of some accuracy)
transform.position = Vector3.Lerp(transform.position, correctPlayerPos, Time.deltaTime * 5);
transform.rotation = Quaternion.Lerp(transform.rotation, correctPlayerRot, Time.deltaTime * 5);
//ADDED CODE BLOCK
if (keycode55 == (KeyCode.LeftControl))
{
transform.Find("baseMale").animation["basemeleeattack1"].wrapMode = WrapMode.Once;
transform.Find("baseMale").animation.Play("basemeleeattack1");
keycode55 = KeyCode.None;
}
//ADDED CODE BLOCK
}
}
And I'm getting an error because of I used this if statement:
if (Input.GetKeyDown(KeyCode.LeftControl))
When I didn't use this if statement im not getting any error but the character continuously play attack animation forever.
Here is the error:
ArgumentOutOfRangeException: Argument is out of range. Parameter name: index System.Collections.Generic.List`1[System.Object].get_Item (Int32 index) (at /Applications/buildAgent/work/84669f285f6a667f/mcs/class/corlib/System.Collections.Generic/List.cs:633) PhotonStream.ReceiveNext () (at Assets/Photon Unity Networking/Plugins/PhotonNetwork/PhotonClasses.cs:244)
PhotonClasses.cs >> link text
If my logic (open a stream like that to make sync the other animations like attack or jump) is wrong, what is the true way to doing this. I need help, really.
Thanks for your interest, Mehmet Mert Yildiran.
Answer by iwaldrop · Jun 19, 2013 at 06:34 AM
You don't need to send control input across the network, only what the control input resulted in. Like the demo shows, it send the position, rotation and velocity over the network to connected clients so that their devices can move the character around according to the player's input.
If you want to send a flag over the network you should set a member variable and send that.
bool someVar;
void Update()
{
someVar = Input.GetKeyDown(KeyCode.LeftControl);
}
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.isWriting)
{
stream.SendNext(someVar);
}
}
But what's important to note here is that you traditionally send states of things, not triggers or events. You want one authority to compute an action to be taken, and then for the interested clients to do the exact same thing.
this "someVar" sending to an object variable so can you suggest a variable or script for this situation ?
The value, someVar, is an object, and should send just fine the way it is. Are you still getting an error when you try it? You could also cast your input to an int and send it directly, but there's no point in getting the same input twice.
Here is the last version of my script and there is a line which is marked (ERROR ERROR ERROR) to cause the same error I dont understand whats the reason:
void OnPhotonSerializeView(PhotonStream stream, Photon$$anonymous$$essageInfo info)
{
if (stream.isWriting)
{
//We own this player: send the others our data
// stream.SendNext((int)controllerScript._characterState);
stream.SendNext(transform.position);
stream.SendNext(transform.rotation);
stream.SendNext(rigidbody.velocity);
//Attack animasyonu icin kod
//stream.SendNext("Ali");
//stream.SendNext(transform.Find("base$$anonymous$$ale").animation.IsPlaying("basemeleeattack1"));
if(transform.Find("base$$anonymous$$ale").animation.IsPlaying("basemeleeattack1"))
{
Debug.Log("animation playing");
//stream.SendNext("test");//what should I send to target, target is an object variable
stream.SendNext($$anonymous$$eyCode.LeftControl);
}
}
else
{
//Network player, receive data
//controllerScript._characterState = (CharacterState)(int)stream.ReceiveNext();
correctPlayerPos = (Vector3)stream.ReceiveNext();
correctPlayerRot = (Quaternion)stream.ReceiveNext();
rigidbody.velocity = (Vector3)stream.ReceiveNext();
keycode55 = ($$anonymous$$eyCode)stream.ReceiveNext();//ERROR ERROR ERROR : Argument is out of range.
//Attack animasyonu icin kod
//keycode55 = ($$anonymous$$eyCode)stream.ReceiveNext();
//Attack animasyonu icin kod
}
}
You have to cast your keycode to an int, not the other way around. Photon can only serialize certain information.
How can i cast it can you edit this script for me ? I found an information about that but how can adabt to my script I dunno.
object[] objarr = new object[] {1,2,3 };
int[] arr= objarr.Cast<int>().ToArray();