I'm working on a Unity 2D multiplayer game using UNet. My problem is that the Client cant send the [Command]
to the server. Im debugging on UnityEditor and a built apk for my android phone.
First I used UnityEditor as Host and the phone as Client, the Debug.Log(SkinName)
APPEARS on the console
.
Then I used UnityEditor as the Client and the phone as Host, the Debug.Log(SkinName)
DOES NOT APPEAR
.
I tried to use [ClientRpc]
instead of [Client]
but it just made it worse, both client and host wont sync. I dont know if I excuted the [ClientRpc] in the right way.(im a noob at UNet)
I've visited other threads/forums and other UNet tutorials to look for solutions but this is what I came up with.
Note: On the other threads that I visited, people mostly suggest that Local Player Authority is unchecked and that is what causing the problem but in this case it is CHECKED
.
Code:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
using Spine;
using Spine.Unity;
using Spine.Unity.Modules;
class SetupLocalPLayer : NetworkBehaviour {
[SyncVar]
public string SkinName;
public string[] CharNames;
public string[] SlotNames;
public string[] AttachmentSuffix;
void Start (){
TransmitSkins ();
SyncSkin ();
if (isLocalPlayer) {
var skeletonrenderer = GetComponent<SkeletonRenderer>();
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],GameController.control.skinName+AttachmentSuffix[z]);
}
GetComponent<PlayerManager> ().enabled = true;
GetComponent<FollowCam> ().enabled = true;
}
}
void Update () {
}
void SyncSkin(){
if (!isLocalPlayer) {
var skeletonrenderer = GetComponent<SkeletonRenderer>();
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],SkinName+AttachmentSuffix[z]);
}
}
}
[Command]
void CmdSetSkin(){
SkinName = GameController.control.skinName;
Debug.Log (SkinName);
}
[Client]
void TransmitSkins(){
if (isLocalPlayer) {
CmdSetSkin ();
}
}
}
Ok, so from what i can see you are trying to sync the skins being used by each player so that each player has the correct skin on every client.
There are a couple of problems with your code, in both syntax and structure.
First lets look at the syntax.
You should absolutely use [ClientRpc]
instead of [Client]
and the method should be named RpcTransmitSkins
. If the script is attached to the player prefab and Local Player Authority is Checked on the network identity then it will work. [Client]
belongs to a different networking API entirely.
Now lets look at the structure.
The basic logic is correct, however, in reality the SyncSkin method will be called long before the Transmission is received.
The Start method will not wait for the transmission, so why not move the skin assignment to the Rpc, that way the other versions of the player will only try to assign their skin once the message is received.
You also have certain actions split up that all clients need to do, getting the SkeletonRenderer for example
Here is how I would restructure your script.
void Start (){
//first, grab the SkeletonRenderer on every version of the player.
//note that it should not be a local var now, but a field in the script
skeletonrenderer = GetComponent<SkeletonRenderer>();
//now do the local player specific stuff
if (isLocalPlayer) {
//transmit the skin name to the other versions of the player
CmdSendSkinRpc(GameController.control.skinName);
//then assign the skin to the local version of the player
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],GameController.control.skinName+AttachmentSuffix[z]);
}
GetComponent<PlayerManager> ().enabled = true;
GetComponent<FollowCam> ().enabled = true;
}
}
[Command]
void CmdSendSkinRpc(string skin){
RpcTransmitSkins(skin);
Debug.Log("Transmitting Skin Named: " + skin);
}
[ClientRpc]
void RpcTransmitSkins(string TransmittedSkinName){
if (!isLocalPlayer) {
Debug.Log("Receiving Skin Named: " + TransmittedSkinName);
for(int z=0;z<SlotNames.Length;z++){
skeletonrenderer.skeleton.SetAttachment(SlotNames[z],TransmittedSkinName+AttachmentSuffix[z]);
}
}
}
Don't be disheartened by the learning curve of the UNET system. It's super confusing to think in multi client and server terms. Even this simple action had me scratching my head for a few minutes :D