- Home /
[Network Howto] synchronizing custom values with local authority
i want to synchronize custom values, like p.e. the X-position of the player via network, similar to how the networkTransform Component does it.
my code looks something like this:
[SyncVar]
float XPos = 0f;
void Update(){
if(!isLocalPlayer){
transform.position.x = XPos; //(simplified, of course you cannot write to transform.position.x)
return;
}
//my Input handling and character controller logic
XPos = currentXPosition;
}
now i spawn one of these for each player with local authority.
problems:
-the server-side client is synched perfectly, but somehow the connected client flickers on the server side between its actual position and XPos = 0 while moving, and defaults to Xpos = 0 when standing still. (or always is on 0)
is a syncVar the wrong way to do this? the example https://unity3d.com/de/learn/tutorials/topics/multiplayer-networking/networking-player-health?playlist=29690 seems to make all SynchVar changes on the Server. but i want to change them with local authority, just like the networkTranform
(-where / how do i set the send rate?)
-or is there an example for a custom NetworkTransform Script somewhere? so i can just grab what i need
i found the send rate & channel configuration: https://docs.unity3d.com/ScriptReference/Networking.NetworkSettingsAttribute.html
a command seems to be the way to update the server data, yet the documentation reccomends to not do it every frame. i am confused. what is the best practice to do this?
Answer by BloodMarked · Jan 31, 2018 at 05:16 PM
this is what i came up with to synchronize custom variables.
potential improvements:
-only send when things change unpredictably (position / animator state change etc)
-idk any other recommendations for optimizations etc hugely appreciated
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class simpleNetworkTester : NetworkBehaviour {
Animator anim;
[SyncVar (hook = "OnServerVarUpdate")]
float XPos = 0f;
[SyncVar]
int animStateHash;
[SyncVar]
float animStateTime;
void Start(){
anim = GetComponent<Animator> ();
}
void Update () {
if (!isLocalPlayer)
return; //only do input and logic on the own player
Vector3 newPos = transform.position;
newPos.x += Input.GetAxis ("Horizontal")*.1f;
transform.position = newPos;
AnimatorStateInfo animSI = anim.GetCurrentAnimatorStateInfo (0);
CmdUpdateServerVars (newPos.x, animSI.fullPathHash, animSI.normalizedTime);
}
void OnServerVarUpdate(float newValue){
if (isLocalPlayer)
return; //do not apply changes on own player
Vector3 syncPos = transform.position;
syncPos.x = newValue;
transform.position = syncPos;
anim.Play (animStateHash, 0, animStateTime);
}
[Command(channel = 1)] //send it through the default unreliable channel
void CmdUpdateServerVars(float newXPos, int _animStateHash, float _animStateTime){
XPos = newXPos;
animStateHash = _animStateHash;
animStateTime = _animStateTime;
}
}