public override void OnEnable() { base.OnEnable(); PlayerControlComponents.OnAdd() .Where(entity => !entity.HasComponent <NetworkPlayerComponent>()) .Subscribe(entity => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var characterController = entity.GetComponent <CharacterController>(); var viewComponent = entity.GetComponent <ViewComponent>(); Observable.EveryUpdate().Subscribe(_ => { if (characterController.isGrounded) { var angle = Vector3.Angle(viewComponent.Transforms[0].forward, mainCamera.transform.forward); if (angle < InvertRange.Min || angle > InvertRange.Max) { playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Horizontal), 0, Input.GetAxis(InputParameters.Vertical)); } else { playerControlComponent.motion = new FixVector3(Input.GetAxis(InputParameters.Vertical), 0, Input.GetAxis(InputParameters.Horizontal)); } playerControlComponent.motion = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion); playerControlComponent.motion *= playerControlComponent.Run; if (Input.GetButton(InputParameters.Jump)) { playerControlComponent.motion.y = playerControlComponent.Jump; } } playerControlComponent.motion.y -= playerControlComponent.Gravity * Time.deltaTime; characterController.Move((Vector3)playerControlComponent.motion * Time.deltaTime); }).AddTo(this.Disposer).AddTo(playerControlComponent.Disposer); }).AddTo(this.Disposer); NetwrokTimeline.OnReverse((entity, result) => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var viewComponent = entity.GetComponent <ViewComponent>(); var playerControlResult = (PlayerControlResult)result[0]; viewComponent.Transforms[0].rotation = playerControlResult.Rotation; playerControlComponent.Follow.rotation = playerControlResult.Follow; viewComponent.Transforms[0].position = playerControlResult.Position; }).AddTo(this.Disposer); NetwrokTimeline.OnForward((entity, userInputData, deltaTime) => { var playerControlComponent = entity.GetComponent <PlayerControlComponent>(); var characterController = entity.GetComponent <CharacterController>(); var viewComponent = entity.GetComponent <ViewComponent>(); var animator = entity.GetComponent <Animator>(); var axisInput = userInputData[0].GetInput <AxisInput>(); var keyInput = userInputData[1].GetInput <KeyInput>(); var mouseInput = userInputData[2].GetInput <MouseInput>(); var playerControlResult = new PlayerControlResult(); var smoothTime = playerControlComponent.smoothTime; var yAngle = Fix64.Zero; playerControlResult.Rotation = viewComponent.Transforms[0].rotation; playerControlResult.Follow = playerControlComponent.Follow.rotation; playerControlResult.Position = viewComponent.Transforms[0].position; if (mouseInput != null && keyInput != null && axisInput != null) { var rotLeftRight = mouseInput.Delta.x * playerControlComponent.MouseSensivity.x * deltaTime; var rotUpDown = mouseInput.Delta.y * playerControlComponent.MouseSensivity.y * deltaTime; if (mouseInput.MouseButtons.Contains(1)) { playerControlComponent.aimTime += deltaTime; if (playerControlComponent.Aim.Value == AimMode.Free && playerControlComponent.aimTime > ShoulderAimTime) { playerControlComponent.Aim.Value = AimMode.Shoulder; } } else { if (playerControlComponent.Aim.Value == AimMode.Free) { if (playerControlComponent.aimTime > 0) { playerControlComponent.Aim.Value = AimMode.AimDownSight; } } else if (playerControlComponent.aimTime > 0) { playerControlComponent.Aim.Value = AimMode.Free; } playerControlComponent.aimTime = 0; } if (playerControlComponent.Aim.Value == AimMode.Free && keyInput.KeyCodes.Contains((int)KeyCode.LeftAlt)) { playerControlComponent.Follow.rotation = (Quaternion)((FixQuaternion)playerControlComponent.Follow.rotation * FixQuaternion.Euler(-rotUpDown, rotLeftRight, 0)); animator.SetFloat(Head_Vertical_f, 0); animator.SetFloat(Body_Vertical_f, 0); smoothTime = SmoothTime; } else { if (smoothTime > 0) { playerControlComponent.Follow.localRotation = (Quaternion)FixQuaternion.Lerp(FixQuaternion.identity, (FixQuaternion)playerControlComponent.Follow.localRotation, FixMath.Clamp01(smoothTime / SmoothTime)); animator.SetFloat(Head_Vertical_f, 0); animator.SetFloat(Body_Vertical_f, 0); smoothTime -= deltaTime; } else { yAngle = ClampAngle(playerControlComponent.Follow.localEulerAngles.x, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max); yAngle = ClampAngle(yAngle - rotUpDown, playerControlComponent.YAngleLimit.Min, playerControlComponent.YAngleLimit.Max); var vertical = 2 * (0.5f - FixMath.Abs(yAngle - playerControlComponent.YAngleLimit.Min) / FixMath.Abs(playerControlComponent.YAngleLimit.Max - playerControlComponent.YAngleLimit.Min)); animator.SetFloat(Head_Vertical_f, 0.5f * (float)vertical); animator.SetFloat(Body_Vertical_f, (float)vertical); viewComponent.Transforms[0].rotation = (Quaternion)((FixQuaternion)viewComponent.Transforms[0].rotation * FixQuaternion.Euler(0, rotLeftRight, 0)); playerControlComponent.Follow.localEulerAngles = (Vector3) new FixVector3(yAngle, 0, 0); } } if (characterController.isGrounded) { playerControlComponent.motion = new FixVector3((float)axisInput.Horizontal, 0, (float)axisInput.Vertical); playerControlComponent.motion = (FixVector3)viewComponent.Transforms[0].TransformDirection((Vector3)playerControlComponent.motion); Fix64 t = 0.75f; Fix64 speed = playerControlComponent.Walk; Fix64 h = FixMath.Abs(axisInput.Horizontal); Fix64 sum = h + FixMath.Abs(axisInput.Vertical); Fix64 horizontal = sum == 0 ? 0 : axisInput.Horizontal * (h / sum); if (playerControlComponent.Aim.Value == AimMode.Shoulder) { t = 0.5f; } else if (playerControlComponent.Aim.Value == AimMode.AimDownSight) { t = 0.25f; } else if (keyInput != null && keyInput.KeyCodes.Contains((int)KeyCode.LeftShift)) { t = 1f; speed = playerControlComponent.Run; } playerControlComponent.Crouched = keyInput.KeyCodes.Contains((int)KeyCode.LeftControl); animator.SetBool(Crouch_b, playerControlComponent.Crouched); if (playerControlComponent.Crouched) { speed = 0; } playerControlComponent.motion *= t * speed; animator.SetFloat(Speed_f, (axisInput.Horizontal != Fix64.Zero || axisInput.Vertical != Fix64.Zero) ? (float)FixMath.Clamp(t, 0.3f, 1f) : 0f); animator.SetFloat(Head_Horizontal_f, 0.25f * (float)horizontal); animator.SetFloat(Body_Horizontal_f, 0.35f * (float)horizontal); } if (keyInput.KeyCodes.Contains((int)KeyCode.Space) && !playerControlComponent.Crouched) { playerControlComponent.motion.y = playerControlComponent.Jump; } } playerControlComponent.motion.y -= playerControlComponent.Gravity * deltaTime; playerControlComponent.smoothTime = smoothTime; characterController.Move((Vector3)(playerControlComponent.motion * deltaTime)); animator.SetBool(Jump_b, playerControlComponent.motion.y > 0); animator.SetBool(Grounded, characterController.isGrounded && playerControlComponent.motion.y <= 0); return(new IUserInputResult[] { playerControlResult }); }).AddTo(this.Disposer); }