context: /************************************************************************************
  Copyright   :   Copyright 2014 Oculus VR, LLC. All Rights reserved.
  Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
  you may not use the Oculus VR Rift SDK except in compliance with the License,
  which is provided at the time of installation or download, or which
  otherwise accompanies this software in either electronic or hard copy form.
  You may obtain a copy of the License at
  http://www.oculusvr.com/licenses/LICENSE-3.2
  Unless required by applicable law or agreed to in writing, the Oculus VR SDK
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  ************************************************************************************/
  
  using UnityEngine;
  using System.Collections.Generic;
  
  /// <summary>
  /// Controls the player's movement in virtual reality.
  /// </summary>
  [RequireComponent(typeof(CharacterController))]
  public class OVRPlayerController : MonoBehaviour
  {
      /// <summary>
      /// The rate acceleration during movement.
      /// </summary>
      public float Acceleration = 0.1f;
  
      /// <summary>
      /// The rate of damping on movement.
      /// </summary>
      public float Damping = 0.3f;
  
      /// <summary>
      /// The rate of additional damping when moving sideways or backwards.
      /// </summary>
      public float BackAndSideDampen = 0.5f;
  
      /// <summary>
      /// The force applied to the character when jumping.
      /// </summary>
      public float JumpForce = 0.3f;
  
      /// <summary>
      /// The rate of rotation when using a gamepad.
      /// </summary>
      public float RotationAmount = 1.5f;
  
      /// <summary>
      /// The rate of rotation when using the keyboard.
      /// </summary>
      public float RotationRatchet = 45.0f;
  
      /// <summary>
      /// The player's current rotation about the Y axis.
      /// </summary>
      private float YRotation = 0.0f;
  
      /// <summary>
      /// If true, tracking data from a child OVRCameraRig will update the direction of movement.
      /// </summary>
      public bool HmdRotatesY = true;
  
      /// <summary>
      /// Modifies the strength of gravity.
      /// </summary>
      public float GravityModifier = 0.379f;
  
      /// <summary>
      /// Give player to move with gravity disabled.
      /// </summary>
      public float NoGravityMovement = 0.0f;
  
      //for HotKeys
      public HotKeys hotkey;
  
  
      private float MoveScale = 1.0f;
      private Vector3 MoveThrottle = Vector3.zero;
      private float FallSpeed = 0.0f;
      private OVRPose? InitialPose;
      private float holdRotationValue;
  
      /// <summary>
      /// If true, each OVRPlayerController will use the player's physical height.
      /// </summary>
      public bool useProfileHeight = true;
  
      protected CharacterController Controller = null;
      protected OVRCameraRig CameraController = null;
  
      private float MoveScaleMultiplier = 1.0f;
      private float RotationScaleMultiplier = 1.0f;
      private bool SkipMouseRotation = false;
      private bool HaltUpdateMovement = false;
      private bool prevHatLeft = false;
      private bool prevHatRight = false;
      private float SimulationRate = 60f;
  
      void Awake()
      {
          Controller = gameObject.GetComponent<CharacterController>();
          holdRotationValue = RotationAmount;
          if (Controller == null)
              Debug.LogWarning("OVRPlayerController: No CharacterController attached.");
  
          // We use OVRCameraRig to set rotations to cameras,
          // and to be influenced by rotation
          OVRCameraRig[] CameraControllers;
          CameraControllers = gameObject.GetComponentsInChildren<OVRCameraRig>();
  
          if (CameraControllers.Length == 0)
              Debug.LogWarning("OVRPlayerController: No OVRCameraRig attached.");
          else if (CameraControllers.Length > 1)
              Debug.LogWarning("OVRPlayerController: More then 1 OVRCameraRig attached.");
          else
              CameraController = CameraControllers[0];
  
          YRotation = transform.rotation.eulerAngles.y;
  
  #if UNITY_ANDROID && !UNITY_EDITOR
  		OVRManager.display.RecenteredPose += ResetOrientation;
  #endif
      }
  
      protected virtual void Update()
      {
          if (Input.GetKeyDown(KeyCode.Escape))
          {
              Application.Quit();
          }
          if (useProfileHeight)
          {
              if (InitialPose == null)
              {
                  InitialPose = new OVRPose()
                  {
                      position = CameraController.transform.localPosition,
                      orientation = CameraController.transform.localRotation
                  };
              }
  
              var p = CameraController.transform.localPosition;
              p.y = OVRManager.profile.eyeHeight - 0.5f * Controller.height;
              p.z = OVRManager.profile.eyeDepth;
              CameraController.transform.localPosition = p;
          }
          else if (InitialPose != null)
          {
              CameraController.transform.localPosition = InitialPose.Value.position;
              CameraController.transform.localRotation = InitialPose.Value.orientation;
              InitialPose = null;
          }
  
          UpdateMovement();
  
          Vector3 moveDirection = Vector3.zero;
  
          float motorDamp = (1.0f + (Damping * SimulationRate * Time.deltaTime));
  
          MoveThrottle.x /= motorDamp;
          MoveThrottle.y = (MoveThrottle.y > 0.0f) ? (MoveThrottle.y / motorDamp) : MoveThrottle.y;
          MoveThrottle.z /= motorDamp;
  
          moveDirection += MoveThrottle * SimulationRate * Time.deltaTime;
  
          // Gravity
          if (Controller.isGrounded && FallSpeed <= 0)
              FallSpeed = ((Physics.gravity.y * (GravityModifier * 0.002f)));
          else
              FallSpeed += ((Physics.gravity.y * (GravityModifier * 0.002f)) * SimulationRate * Time.deltaTime);
  
          moveDirection.y += FallSpeed * SimulationRate * Time.deltaTime;
  
          // Offset correction for uneven ground
          float bumpUpOffset = 0.0f;
  
          if (Controller.isGrounded && MoveThrottle.y <= 0.001f)
          {
              bumpUpOffset = Mathf.Max(Controller.stepOffset, new Vector3(moveDirection.x, 0, moveDirection.z).magnitude);
              moveDirection -= bumpUpOffset * Vector3.up;
          }
  
          Vector3 predictedXZ = Vector3.Scale((Controller.transform.localPosition + moveDirection), new Vector3(1, 0, 1));
  
          // Move contoller
          Controller.Move(moveDirection);
          // Stop controller after movement;
          Stop();
  
          Vector3 actualXZ = Vector3.Scale(Controller.transform.localPosition, new Vector3(1, 0, 1));
  
          if (predictedXZ != actualXZ)
              MoveThrottle += (actualXZ - predictedXZ) / (SimulationRate * Time.deltaTime);
      }
  
      public virtual void UpdateMovement()
      {
          if (HaltUpdateMovement)
              return;
  
          bool moveForward = hotkey.moveForward;
          bool moveLeft = hotkey.moveLeft;
          bool moveRight = hotkey.moveRight;
          bool moveBack = hotkey.moveBack;
  
          //adding moveing up and moving down functions
          bool moveUpDown = hotkey.moveY;
          bool dpad_move = false;
  
          if (OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.Up))
          {
              moveForward = true;
              dpad_move = true;
  
          }
          if (OVRGamepadController.GPC_GetButton(OVRGamepadController.Button.Down))
          {
              moveBack = true;
              dpad_move = true;
          }
  
          MoveScale = 1.0f;
  
  
gt:         if ((moveForward && moveLeft) || (moveForward && moveRight) ||