void SendInputs(Inputs inp, Results res) { #else void SendInputs(Inputs inp) { #endif if (!isLocalPlayer || isServer) { return; } if (inputWriter == null) { inputWriter = new NetworkWriter(); } if (inpSend == null) { inpSend = new InputSend(); } inputWriter.SeekZero(); inputWriter.StartMessage(inputMessage); #if (CLIENT_TRUST) inpRes = new InputResult(); inpRes.inp = inp; inpRes.res = res; inputWriter.Write(inpRes); #else inpSend.inp = inp; inputWriter.Write(inpSend); #endif inputWriter.FinishMessage(); myClient.SendWriter(inputWriter, GetNetworkChannel()); } void OnSendInputs(NetworkMessage msg) { #if (CLIENT_TRUST) inpRes = msg.ReadMessage <InputResult> (); Inputs inp = inpRes.inp; Results res = inpRes.res; #else Inputs inp = msg.ReadMessage <InputSend> ().inp; #endif #if (SIMULATE) #if (CLIENT_TRUST) StartCoroutine(SendInputsC(inp, res)); #else StartCoroutine(SendInputsC(inp)); #endif } #if (CLIENT_TRUST) IEnumerator SendInputsC(Inputs inp, Results res) { #else IEnumerator SendInputsC(Inputs inp) { #endif yield return(new WaitForSeconds(UnityEngine.Random.Range(0.21f, 0.28f))); #endif if (!isLocalPlayer) { if (clientInputs.Count > data.clientInputsBuffer) { clientInputs.RemoveAt(0); } if (!ClientInputsContainTimestamp(inp.timestamp)) { clientInputs.Add(inp); } #if (CLIENT_TRUST) tempResults = res; #endif currentTFixedUpdates += sendUpdates; if (data.debug && lastTick + 1 != inp.timestamp && lastTick != -1) { Debug.Log("Missing tick " + lastTick + 1); } lastTick = inp.timestamp; } } //Results part public override void OnDeserialize(NetworkReader reader, bool initialState)
//Actual movement code. Mostly isolated, except transform Results MoveCharacter(Results inpRes, Inputs inp, float deltaMultiplier, Vector3 maxSpeed) { inp.y = Mathf.Clamp(curInput.y, dataInp.camMinY, dataInp.camMaxY); if (inp.x > 360f) { inp.x -= 360f; } else if (inp.x < 0f) { inp.x += 360f; } Vector3 pos = myTransform.position; Quaternion rot = myTransform.rotation; myTransform.position = inpRes.position; myTransform.rotation = inpRes.rotation; Vector3 tempSpeed = myTransform.InverseTransformDirection(inpRes.speed); myTransform.rotation = Quaternion.Euler(new Vector3(0, inp.x, 0)); //Character sliding of surfaces if (!inpRes.isGrounded) { inpRes.speed.x += (1f - inpRes.groundNormal.y) * inpRes.groundNormal.x * (inpRes.speed.y > 0 ? 0 : -inpRes.speed.y) * (1f - data.slideFriction); inpRes.speed.x += (1f - inpRes.groundNormal.y) * inpRes.groundNormal.x * (inpRes.speed.y < 0 ? 0 : inpRes.speed.y) * (1f - data.slideFriction); inpRes.speed.z += (1f - inpRes.groundNormal.y) * inpRes.groundNormal.z * (inpRes.speed.y > 0 ? 0 : -inpRes.speed.y) * (1f - data.slideFriction); inpRes.speed.z += (1f - inpRes.groundNormal.y) * inpRes.groundNormal.z * (inpRes.speed.y < 0 ? 0 : -inpRes.speed.y) * (1f - data.slideFriction); } Vector3 localSpeed = myTransform.InverseTransformDirection(inpRes.speed); Vector3 localSpeed2 = Vector3.Lerp(myTransform.InverseTransformDirection(inpRes.speed), tempSpeed, data.velocityTransferCurve.Evaluate(Mathf.Abs(inpRes.rotation.eulerAngles.y - inp.x) / (deltaMultiplier * data.velocityTransferDivisor))); if (!inpRes.isGrounded && data.strafing) { AirStrafe(ref inpRes, ref inp, ref deltaMultiplier, ref maxSpeed, ref localSpeed, ref localSpeed2); } else { localSpeed = localSpeed2; } BaseMovement(ref inpRes, ref inp, ref deltaMultiplier, ref maxSpeed, ref localSpeed); float tY = myTransform.position.y; inpRes.speed = transform.TransformDirection(localSpeed); hitNormal = new Vector3(0, 0, 0); inpRes.speed.x = data.finalSpeedCurve.Evaluate(inpRes.speed.x); inpRes.speed.y = data.finalSpeedCurve.Evaluate(inpRes.speed.y); inpRes.speed.z = data.finalSpeedCurve.Evaluate(inpRes.speed.z); controller.Move(inpRes.speed * deltaMultiplier); //This code continues after OnControllerColliderHit gets called (if it does) if (Vector3.Angle(Vector3.up, hitNormal) <= data.slopeLimit) { inpRes.isGrounded = true; } else { inpRes.isGrounded = false; } float speed = inpRes.speed.y; inpRes.speed = (transform.position - inpRes.position) / deltaMultiplier; if (inpRes.speed.y > 0) { inpRes.speed.y = Mathf.Min(inpRes.speed.y, Mathf.Max(0, speed)); } else { inpRes.speed.y = Mathf.Max(inpRes.speed.y, Mathf.Min(0, speed)); } //inpRes.speed.y = speed; float gpt = 1f; float gp = myTransform.position.y; //WIP, broken, Handles hitting ground while spacebar is pressed. It determines how much time was left to move based on at which height the player hit the ground. Some math involved. if (data.handleMidTickJump && !inpRes.isGrounded && tY - gp >= 0 && inp.jump && (controller.isGrounded || Physics.Raycast(myTransform.position + controller.center, Vector3.down, (controller.height / 2) + (controller.skinWidth * 1.5f)))) { float oSpeed = inpRes.speed.y; gpt = (tY - gp) / (-oSpeed); inpRes.speed.y = data.speedJump + ((Physics.gravity.y / 2) * Mathf.Abs((1f - gpt) * deltaMultiplier)); Debug.Log(inpRes.speed.y + " " + gpt); controller.Move(myTransform.TransformDirection(0, inpRes.speed.y * deltaMultiplier, 0)); inpRes.isGrounded = true; Debug.DrawLine(new Vector3(myTransform.position.x, gp, myTransform.position.z), myTransform.position, Color.blue, deltaMultiplier); inpRes.jumped = true; } if (data.snapSize > 0f) { myTransform.position = new Vector3(Mathf.Round(myTransform.position.x * snapInvert) * data.snapSize, Mathf.Round(myTransform.position.y * snapInvert) * data.snapSize, Mathf.Round(myTransform.position.z * snapInvert) * data.snapSize); } if (inpRes.isGrounded) { localSpeed.y = Physics.gravity.y * Mathf.Clamp(deltaMultiplier, 1f, 1f); } inpRes = new Results(myTransform.position, myTransform.rotation, hitNormal, inp.y, inpRes.speed, inpRes.isGrounded, inpRes.jumped, inpRes.crouch, gp, gpt, inp.timestamp); myTransform.position = pos; myTransform.rotation = rot; return(inpRes); }