I have a game where players are dropped into an arena from a Lobby. Everything is working well, except the traps. There are animated sawblades that slide back and forth in the Z direction. On the host, everything is okay, as is expected. On the clients, their position is shifted (so that they dont even reach the same place as the host’s). However, because I am properly using commands, the player still dies appropriately only when they are hit by the sawblades actual position (server/host position).
The issue is, when using a custom script, their position is not synced. When using a Network Transform component, their transform is constantly flickering, however one of the two flickering positions is the actual correct position.
Here is my custom sync position script:
using UnityEngine;
using System.Collections;
using UnityEngine.Networking;
public class CTFSawMove : NetworkBehaviour {
[SyncVar (hook="SyncPositionValues")] private Vector3 syncPos;
private Vector3 lastPos;
private float threshold = 0.2f;
private float lerpRate = 16.0f;
[SerializeField] private Transform myTransform;
public int speed;
public int length;
private float offset;
public int bladeDamage;
public Animator sawAnimation;
public override void OnStartLocalPlayer() {
sawAnimation = myTransform.GetComponent<Animator> ();
}
public override void OnStartClient() {
sawAnimation = myTransform.GetComponent<Animator> ();
}
void Start () {
offset = myTransform.position.z;
syncPos = new Vector3(myTransform.position.x, myTransform.position.y, myTransform.position.z);
}
void Update() {
MoveSaw ();
LerpPosition ();
}
void MoveSaw() {
myTransform.position = new Vector3(transform.position.x, transform.position.y, offset + (Mathf.PingPong(Time.time * speed, length)));
}
void LerpPosition() {
myTransform.position = Vector3.Lerp (myTransform.position, syncPos, Time.deltaTime * lerpRate);
}
void FixedUpdate () {
TransmitPosition ();
}
[Command]
void CmdProvidePositionToServer(Vector3 pos) {
syncPos = pos;
}
[ClientCallback]
void TransmitPosition() {
if( isLocalPlayer && Vector3.Distance(myTransform.position, lastPos) > threshold ) {
CmdProvidePositionToServer(myTransform.position);
lastPos = myTransform.position;
}
}
[Client]
void SyncPositionValues(Vector3 latestPos) {
syncPos = latestPos;
}
void OnTriggerEnter(Collider o){
if (o.transform.tag == "Player" || o.transform.tag == "You") {
CmdTellServerWhoWasHitByBlades (o.transform.name, bladeDamage);
}
}
[Command]
void CmdTellServerWhoWasHitByBlades(string hitName, int dmg) {
GameObject go = GameObject.Find (hitName);
go.GetComponent<CTFPlayerHealth> ().DeductHealth (dmg);
}
}
I’ve been googling this for quite some time, but it seems there isn’t a single person who has ever had trouble with syncing non-player objects. Everyone just has issues with non-player objects that need authority.