using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Timing; using FishNet.Object; using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace FishNet.Example.ColliderRollbacks { /// /// DEMO. CODE IS NOT OPTIMIZED. /// Shows where an object was when client hit it, and where it was after server rolled it back. /// public class RollbackVisualizer : NetworkBehaviour { [SerializeField] private GameObject _originalPrefab; [SerializeField] private GameObject _rollbackPrefab; [SerializeField] private TextCanvas _textCanvasPrefab; /// /// Average accuracy over the past 30 shots. /// private List _accuracyAverage = new List(); private void OnDisable() { _accuracyAverage.Clear(); } /// /// Shows difference between where object was when client shot it, and where it was after rollback. /// /// /// [Server] public void ShowDifference(NetworkObject clientObject, Vector3 original, Vector3 rolledBack) { //Only send to client if not host. if (!base.IsHost) { float difference = Vector3.Distance(original, rolledBack); PrintAverage(false, difference, base.NetworkManager); TargetShowDifference(clientObject.Owner, original, rolledBack); } } [TargetRpc] private void TargetShowDifference(NetworkConnection conn, Vector3 original, Vector3 rollback) { Instantiate(_originalPrefab, original, transform.rotation); Instantiate(_rollbackPrefab, rollback, transform.rotation); float difference = Vector3.Distance(original, rollback); string accuracyText = PrintAverage(true, difference, base.NetworkManager); TextCanvas tc = Instantiate(_textCanvasPrefab); tc.SetText(accuracyText); } /// /// Prints an average accuracy, returning what was printed. /// /// True if difference is received from the server. private string PrintAverage(bool fromServer, float difference, NetworkManager nm) { //If clientHost... if (nm.IsHost) { string result = $"Accuracy will not show properly when as clientHost.{Environment.NewLine}Use a separate client and server for testing."; Debug.Log(result); return result; } else { _accuracyAverage.Add(difference); if (_accuracyAverage.Count > 20) _accuracyAverage.RemoveAt(0); string currentHit = $"Accuracy is within {difference.ToString("0.0000")} units."; string allHit = $"{_accuracyAverage.Count} hit average is {(_accuracyAverage.Sum() / _accuracyAverage.Count).ToString("0.0000")}."; string result = $"{currentHit} {allHit}"; Debug.Log(result); return result; } } } }