Hi! I am using photon with unity and im trying to sync players skins and hats, But it doesn't work.

The whole answer can be found below.

Please note: The Photon forum is closed permanently. After many dedicated years of service we have made the decision to retire our forum and switch to read-only: we've saved the best to last! And we offer you support through these channels:

Try Our
Documentation

Please check if you can find an answer in our extensive documentation on PUN.

Join Us
on Discord

Meet and talk to our staff and the entire Photon-Community via Discord.

Read More on
Stack Overflow

Find more information on Stack Overflow (for Circle members only).

Write Us
an E-Mail

Feel free to send your question directly to our developers.

Hi! I am using photon with unity and im trying to sync players skins and hats, But it doesn't work.

PixelTurtle
2022-06-09 05:38:56

Any suggestion? I alredy tried so many solutions. Here is my code

public SpriteRenderer Skin;

private SpriteRenderer Hat;

public bool online;

ExitGames.Client.Photon.Hashtable playerProperties = new ExitGames.Client.Photon.Hashtable();

Player player;

PhotonView pView;

public PhotonView skPview;

private void Start()

{

Hat = GetComponent();

if (!online)

{

if (PlayerPrefs.HasKey("actualHat"))

{

Hat.sprite =

Container.staticHats[Container.OrderH[PlayerPrefs.GetInt("actualHat")]];

}

if (PlayerPrefs.HasKey("actualSkin"))

Skin.sprite = Container.staticSkins[Container.OrderS[PlayerPrefs.GetInt("actualSkin")]];

}

else

{

playerProperties["skin"] = PlayerPrefs.GetInt("actualSkin");

playerProperties["hat"] = PlayerPrefs.GetInt("actualHat");

PhotonNetwork.SetPlayerCustomProperties(playerProperties);

pView = GetComponent();

LoadHat();

}

}

void LoadHat()

{

if (pView.IsMine && skPview.IsMine)

{

playerProperties.Clear();

playerProperties.Add("skin", PlayerPrefs.GetInt("actualSkin"));

playerProperties.Add("hat", PlayerPrefs.GetInt("actualHat"));

PhotonNetwork.LocalPlayer.SetCustomProperties(playerProperties);

Hat.sprite = Container.staticHats[PlayerPrefs.GetInt("actualHat")];

Skin.sprite = Container.staticSkins[PlayerPrefs.GetInt("actualSkin")];

}

else

{

playerProperties.Clear();

player = pView.Owner;

Hat.sprite = Container.staticHats[(int)player.CustomProperties["actualHat"]];

Skin.sprite = Container.staticSkins[(int)player.CustomProperties["actualSkin"]];

}

}

Comments

Dibbie
2022-06-16 22:24:17

I may be misunderstanding your goal, so assuming that you only need to do this once when they first spawn or join a room or on some other type of "one-time" action, then you could probably use RaiseEvent (or RPC) and send an ID to all the other players about your skin, hat, and any other cosmetics or items specific to your players - one thing to keep in mind, is try to minimize the amount of data being sent through either a RPC or RaiseEvent, an int (or byte) ID might be best in this case - for example (using ScriptableObjects):

public class FancyHat : ScriptableObject

{

public int ID;

public string name;

//anything else you might need to know about a hat

}

public class PlayerCosmetics : MonoBehaviour //this would be whatever script exists on your players intended to send out their cosmetic hat choices

{

public List allHatsInGame = new List();

public FancyHat playerHat;

void Start()

{

PhotonNetwork.RaiseEvent(someByteValue, playerHat.ID, PhotonTargets.Others);

}

void OnEnable()

{

PhotonNetwork.AddCallbackTarget(this);

}

void OnDisable()

{

PhotonNetwork.RemoveCallbackTarget(this);

}

void OnEvent(EventData photonEvent)

{

byte eventCode = photonEvent.Code;

if (eventCode == someByteValue)

{

int data = (int)photonEvent.CustomData; //if you need to send more than just 1 ID over, this can be of type object[] instead

if(!photonView.isMine){playerHat = GetHat(data);} //at this point, you can check playerHat and do whatever you need locally - spawn a object, set a texture, etc

}

}

public FancyHat GetHat(int ID) {return allHatsInGame.FirstOrDefault(x => x.ID == ID);} //requires using System.Linq; this can also be done with a for-loop

}

(this is just some example code, it may not work verbatim)

Since every player would have the same ScriptableObject data in their version of the game, you can do a local lookup for the ID with Linq and get the relevant skin/hat textures/models/sounds/etc you might need, as long as you have a list of your scriptable objects/hats/skins/etc - it doesnt HAVE to be a ScriptableObject, it could be a serialized class or just a regular data class as long as you can make a list of it and have some way of setting/assigning the ID's and project assets - here is the docs for RaiseEvent as well, if you are unfamiliar with them: https://doc.photonengine.com/en-us/pun/current/gameplay/rpcsandraiseevent

Back to top