Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections.Generic;
- using UnityEngine.Networking;
- //using UnityEngine.UI;
- public class playerControllerPrediction : NetworkBehaviour
- {
- //How often to send inputs to server
- public int sendRate = 10;
- public playerInput playerInput;
- public Rigidbody2D playerRigidbody;
- //Speeds of character movement
- public int walkSpeed = 2;
- public int runSpeed = 4;
- public int curSpeed;
- //Vector 2 pulled from input script
- [SyncVar]
- public Vector2 inputVector;
- public Vector2 playerVelocity;
- private Vector2 lastPos;
- //pos of character on server
- [SyncVar (hook = "GetServerPosition")]
- public Vector2 serverPos;
- //Dictionaries containing timestamps and positions
- private Dictionary<float, Vector2> serverPosDict = new Dictionary<float, Vector2>();
- private Dictionary<float, Vector2> clientPosDict = new Dictionary<float, Vector2>();
- public float serverTick;
- public float clientTick;
- private float locationTolerance = 0.1f;
- //Testing Latency addition
- //getting it in another script, in milliseconds
- private playerNetworkSetup setupScript;
- public float latency;
- public override void OnStartLocalPlayer()
- {
- setupScript = GetComponent<playerNetworkSetup>();
- playerRigidbody = GetComponent<Rigidbody2D>();
- playerInput = GetComponentInChildren<playerInput>();
- float sendRateInSeconds = (1 / (float)sendRate);
- InvokeRepeating("NetworkSend", sendRateInSeconds, sendRateInSeconds);
- }
- //Client doesn't need to get the rigidbody or the server would set the client's velocity
- public override void OnStartServer()
- {
- playerRigidbody = GetComponent<Rigidbody2D>();
- }
- //just to only send to server when moving
- void Update ()
- {
- Vector2 curPos = transform.position;
- playerVelocity = (curPos - lastPos) / Time.deltaTime;
- lastPos = transform.position;
- }
- void FixedUpdate()
- {
- if (isLocalPlayer)
- {
- inputVector = playerInput.inputVector.normalized; //Normalized before sending
- if (playerInput.shift)
- {
- curSpeed = runSpeed;
- }
- else
- {
- curSpeed = walkSpeed;
- }
- }
- }
- //SYNCVARS ONLY SYNC TO THE CLIENTS NOT THE SERVER
- //This code is now working because we are setting the SyncVar's
- //in the command, and propogating these changes to the client.
- void NetworkSend ()
- {
- if (isLocalPlayer)
- {
- if (inputVector == Vector2.zero && playerVelocity == Vector2.zero)
- {
- return;
- }
- else
- {
- SendServerPlayerInputs();
- ClientPrediction();
- }
- }
- }
- [Command]
- void CmdCalculatePlayerMovement(Vector2 clientInputs, int speed)
- {
- inputVector = clientInputs;
- playerRigidbody.velocity = inputVector * speed;
- serverPos = new Vector2(transform.position.x, transform.position.y);
- }
- [ClientCallback]
- void SendServerPlayerInputs()
- {
- CmdCalculatePlayerMovement(inputVector, curSpeed);
- }
- [ClientCallback]
- void ClientPrediction ()
- {
- if (!isServer)
- {
- latency = (setupScript.latency / 100f);
- playerRigidbody.velocity = inputVector * curSpeed;
- clientTick = (Mathf.Round(Time.time * 100) / 100);
- if (!clientPosDict.ContainsKey(clientTick))
- {
- clientPosDict.Add(clientTick, transform.position);
- }
- //Clamp count to 20 / 200ms
- if (clientPosDict.ContainsKey(clientTick - 20))
- {
- clientPosDict.Remove(clientTick - 20);
- }
- if (serverPosDict.ContainsKey(serverTick - 20))
- {
- serverPosDict.Remove(serverTick - 20);
- }
- //Check server dictionary
- if (serverPosDict.Count == 0)
- {
- return;
- }
- else
- {
- //If server dictionary contains the client's tick, check for error.
- if (clientPosDict.ContainsKey(serverTick + latency))
- {
- Debug.Log("Fired");
- float errorX = serverPosDict[serverTick].x - clientPosDict[serverTick + latency].x;
- float errorY = serverPosDict[serverTick].y - clientPosDict[serverTick + latency].y;
- if (Mathf.Abs(errorX) > locationTolerance)
- {
- Debug.Log("Error in X: " + errorX);
- //Correct error in x
- }
- if (Mathf.Abs(errorY) > locationTolerance)
- {
- Debug.Log("Error in Y: " + errorY);
- //correct error in y
- }
- }
- }
- }
- }
- //hook function for getting the server position
- //timestamp relative to localplayer?
- [ClientCallback]
- void GetServerPosition (Vector2 pos)
- {
- if (isLocalPlayer)
- {
- serverTick = Mathf.Round(Time.time * 100) / 100;
- if (!serverPosDict.ContainsKey(serverTick))
- {
- serverPosDict.Add(serverTick, new Vector2(pos.x, pos.y));
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment