#player info syncing
1 messages · Page 1 of 1 (latest)
network variables
everything is done in the OnClientConnected method
i use playerprefs
for the character prefab
and the name
GameObject player = Instantiate(characterButtonHandler.Prefabs[PlayerPrefs.GetInt("prefabIndex")].characterPrefab);
It works on my computer locally
no matter how many clients i have
but for connections from the outside it doesnt
player prefs are only stored locally. the server will have no idea what the remote player prefab or name are
the Prefabs array is local
and the prefab index is also locally stored via playerprefs
the server will still need to know what is getting spawned. At the very least an array index will need to be sent over the network
how would i implement that?
I have a client send a RPC with the index of the character to spawn
@full raft why don't you have each client set their own info?
You can use a network variable with owner write permissions
just depends on when you are setting those variables
idk how else i could do it
What info are you trying to sync?
a name string?
What else
Why are you using playerprefs again?
the character selection menu is a different menu , you select your character then you go into the join menu
so i need it locally saved till the server needs it
so the character selection itself has nothing to do with the server
all the server needs is the index
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CharacterButtonHandler : MonoBehaviour
{
[SerializeField]private List<Button> characterButtons = new List<Button>();
[SerializeField] public List<Character> Prefabs = new List<Character>();
[SerializeField] private GameObject[] takenUI = null;
[SerializeField] public JoinMenu joinMenu = null;
[SerializeField] GameObject MainMenu = null;
public Animator animator;
private void Start()
{
animator = GetComponent<Animator>();
foreach (Button button in characterButtons)
{
button.onClick.AddListener(() => joinMenu.SetPlayerGameObject(characterButtons.IndexOf(button)));
button.onClick.AddListener(() => SetButtonTaken(characterButtons.IndexOf(button)));
}
}
private void SetButtonTaken(int index)
{
foreach(Button button in characterButtons)
{
takenUI[characterButtons.IndexOf(button)].SetActive(false);
}
takenUI[index].SetActive(true);
}
private void Awake()
{
SetButtonTaken(PlayerPrefs.GetInt("prefabIndex",0));
}
public void InitiateAnimationReturn()
{
animator.SetBool("Return", true);
MainMenu.SetActive(true);
}
public void DisableMenu()
{
animator.SetBool("Return", false);
gameObject.SetActive(false);
}
}
everything here is local
Fair enough as a solution
but all the more reason for each client to sync their own info
If clients are setting their info offline, no reason for the server to have to retrieve and sync that
will save you a lot of headache if each client just syncs their own stuff, less calls
Yeah i mean i'd need to give the OnClientConnected method extra parameters and just do the playerprefs.get stuff befotehand and then pass it to that method
for clients to sync their info?
Only issue is im using the onclientconnected callback aswell for this to work
Hold on
i can do
PlayerPrefs.GetString("username")
PlayerPrefs.GetInt("prefabIndex")
in the HostOrConnect function
so it gets called locally
but then i'd need to keep passing on these values
and since i use callbacks
no idea how i would do so
if you are selecting character after connecting to the host then it would be way easier to use network variables
player name already is
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Unity.Networking;
using Unity.Netcode;
using TMPro;
using UnityEditor;
using Unity.Netcode.Transports.UTP;
using Unity.Collections;
using System;
public class DisplayPlayerName : Unity.Netcode.NetworkBehaviour
{
public NetworkVariable<NetPlayerName> PlayerName = new NetworkVariable<NetPlayerName>(new NetPlayerName() { username = "" });
public override void OnNetworkSpawn()
{
Debug.Log("Spawned");
base.OnNetworkSpawn();
if (IsServer)
{
PlayerName.OnValueChanged += OnPlayerNameChanged;
string username = PlayerPrefs.GetString("username");
PlayerName.Value = new NetPlayerName() { username = username };
}
UpdatePlayerNameUI(PlayerName.Value.username.ToString());
}
private void OnPlayerNameChanged(NetPlayerName previousValue, NetPlayerName newValue)
{
Debug.Log($"Player {OwnerClientId} changed name from {previousValue.username} to {newValue.username}");
UpdatePlayerNameUI(newValue.username.ToString());
}
public void SetPlayerName(string name)
{
if (IsServer)
{
PlayerName.Value = new NetPlayerName() { username = name };
}
}
private void UpdatePlayerNameUI(string name)
{
GetComponentInChildren<TMP_Text>().text = name;
}
}
public struct NetPlayerName : INetworkSerializable, System.IEquatable<NetPlayerName>
{
public FixedString64Bytes username;
public bool Equals(NetPlayerName other)
{
return username.Equals(other.username);
}
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref username);
}
}
this is for the player tag
and im seeing just now, i also used player prefs here
which probably wouldn't work
man i don't know, im lost, lol.
that will work fine. you have to set the network variable to owner write permissions
You can also simplify that with NetworkVariable<FixedString64Bytes> PlayerName = new(writePerm: NetworkVariableWritePermission.Owner);
I think you just need to forget about PlayerPrefs after Networking starts as well, it's the root of the problem with your info getting mixed up
Just have each player set their info to PlayerPrefs offline in the menu, and when they join assign the info from PlayerPrefs to two NetworkVariables
and then forget about PlayerPrefs
because you have NetworkVariables syncing your info for that player
I would only use player prefs if you need it to persist offline or between scenes.