Advertisement
Guest User

Untitled

a guest
May 20th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.56 KB | None | 0 0
  1. using System;
  2. using UnityEngine;
  3.  
  4. /// <summary>
  5. /// Controls the player's movement in virtual reality.
  6. /// </summary>
  7. [RequireComponent(typeof(CharacterController))]
  8. public class OVRPlayerController : MonoBehaviour
  9. {
  10. /// <summary>
  11. /// The rate acceleration during movement.
  12. /// </summary>
  13. public float Acceleration = 0.1f;
  14.  
  15. /// <summary>
  16. /// The rate of damping on movement.
  17. /// </summary>
  18. public float Damping = 0.3f;
  19.  
  20. /// <summary>
  21. /// The rate of additional damping when moving sideways or backwards.
  22. /// </summary>
  23. public float BackAndSideDampen = 0.5f;
  24.  
  25. /// <summary>
  26. /// The force applied to the character when jumping.
  27. /// </summary>
  28. public float JumpForce = 0.3f;
  29.  
  30. /// <summary>
  31. /// The rate of rotation when using a gamepad.
  32. /// </summary>
  33. public float RotationAmount = 1.5f;
  34.  
  35. /// <summary>
  36. /// The rate of rotation when using the keyboard.
  37. /// </summary>
  38. public float RotationRatchet = 45.0f;
  39.  
  40. /// <summary>
  41. /// The player will rotate in fixed steps if Snap Rotation is enabled.
  42. /// </summary>
  43. [Tooltip("The player will rotate in fixed steps if Snap Rotation is enabled.")]
  44. public bool SnapRotation = true;
  45.  
  46. /// <summary>
  47. /// How many fixed speeds to use with linear movement? 0=linear control
  48. /// </summary>
  49. [Tooltip("How many fixed speeds to use with linear movement? 0=linear control")]
  50. public int FixedSpeedSteps;
  51.  
  52. /// <summary>
  53. /// If true, reset the initial yaw of the player controller when the Hmd pose is recentered.
  54. /// </summary>
  55. public bool HmdResetsY = true;
  56.  
  57. /// <summary>
  58. /// If true, tracking data from a child OVRCameraRig will update the direction of movement.
  59. /// </summary>
  60. public bool HmdRotatesY = true;
  61.  
  62. /// <summary>
  63. /// Modifies the strength of gravity.
  64. /// </summary>
  65. public float GravityModifier = 0.379f;
  66.  
  67. /// <summary>
  68. /// If true, each OVRPlayerController will use the player's physical height.
  69. /// </summary>
  70. public bool useProfileData = true;
  71.  
  72. /// <summary>
  73. /// The CameraHeight is the actual height of the HMD and can be used to adjust the height of the character controller, which will affect the
  74. /// ability of the character to move into areas with a low ceiling.
  75. /// </summary>
  76. [NonSerialized]
  77. public float CameraHeight;
  78.  
  79. /// <summary>
  80. /// This event is raised after the character controller is moved. This is used by the OVRAvatarLocomotion script to keep the avatar transform synchronized
  81. /// with the OVRPlayerController.
  82. /// </summary>
  83. public event Action<Transform> TransformUpdated;
  84.  
  85. /// <summary>
  86. /// This bool is set to true whenever the player controller has been teleported. It is reset after every frame. Some systems, such as
  87. /// CharacterCameraConstraint, test this boolean in order to disable logic that moves the character controller immediately
  88. /// following the teleport.
  89. /// </summary>
  90. [NonSerialized] // This doesn't need to be visible in the inspector.
  91. public bool Teleported;
  92.  
  93. /// <summary>
  94. /// This event is raised immediately after the camera transform has been updated, but before movement is updated.
  95. /// </summary>
  96. public event Action CameraUpdated;
  97.  
  98. /// <summary>
  99. /// This event is raised right before the character controller is actually moved in order to provide other systems the opportunity to
  100. /// move the character controller in response to things other than user input, such as movement of the HMD. See CharacterCameraConstraint.cs
  101. /// for an example of this.
  102. /// </summary>
  103. public event Action PreCharacterMove;
  104.  
  105. /// <summary>
  106. /// When true, user input will be applied to linear movement. Set this to false whenever the player controller needs to ignore input for
  107. /// linear movement.
  108. /// </summary>
  109. public bool EnableLinearMovement = true;
  110.  
  111. /// <summary>
  112. /// When true, user input will be applied to rotation. Set this to false whenever the player controller needs to ignore input for rotation.
  113. /// </summary>
  114. public bool EnableRotation = true;
  115.  
  116. /// <summary>
  117. /// Rotation defaults to secondary thumbstick. You can allow either here. Note that this won't behave well if EnableLinearMovement is true.
  118. /// </summary>
  119. public bool RotationEitherThumbstick = false;
  120.  
  121. protected CharacterController Controller = null;
  122. protected OVRCameraRig CameraRig = null;
  123.  
  124. private float MoveScale = 1.0f;
  125. private Vector3 MoveThrottle = Vector3.zero;
  126. private float FallSpeed = 0.0f;
  127. private OVRPose? InitialPose;
  128. public float InitialYRotation { get; private set; }
  129. private float MoveScaleMultiplier = 1.0f;
  130. private float RotationScaleMultiplier = 1.0f;
  131. private bool SkipMouseRotation = true; // It is rare to want to use mouse movement in VR, so ignore the mouse by default.
  132. private bool HaltUpdateMovement = false;
  133. private bool prevHatLeft = false;
  134. private bool prevHatRight = false;
  135. private float SimulationRate = 60f;
  136. private float buttonRotation = 0f;
  137. private bool ReadyToSnapTurn; // Set to true when a snap turn has occurred, code requires one frame of centered thumbstick to enable another snap turn.
  138.  
  139. void Start()
  140. {
  141. // Add eye-depth as a camera offset from the player controller
  142. var p = CameraRig.transform.localPosition;
  143. p.z = OVRManager.profile.eyeDepth;
  144. CameraRig.transform.localPosition = p;
  145. }
  146.  
  147. void Awake()
  148. {
  149. Controller = gameObject.GetComponent<CharacterController>();
  150.  
  151. if (Controller == null)
  152. Debug.LogWarning("OVRPlayerController: No CharacterController attached.");
  153.  
  154. // We use OVRCameraRig to set rotations to cameras,
  155. // and to be influenced by rotation
  156. OVRCameraRig[] CameraRigs = gameObject.GetComponentsInChildren<OVRCameraRig>();
  157.  
  158. if (CameraRigs.Length == 0)
  159. Debug.LogWarning("OVRPlayerController: No OVRCameraRig attached.");
  160. else if (CameraRigs.Length > 1)
  161. Debug.LogWarning("OVRPlayerController: More then 1 OVRCameraRig attached.");
  162. else
  163. CameraRig = CameraRigs[0];
  164.  
  165. InitialYRotation = transform.rotation.eulerAngles.y;
  166. }
  167.  
  168. void OnEnable()
  169. {
  170. OVRManager.display.RecenteredPose += ResetOrientation;
  171.  
  172. if (CameraRig != null)
  173. {
  174. CameraRig.UpdatedAnchors += UpdateTransform;
  175. }
  176. }
  177.  
  178. void OnDisable()
  179. {
  180. OVRManager.display.RecenteredPose -= ResetOrientation;
  181.  
  182. if (CameraRig != null)
  183. {
  184. CameraRig.UpdatedAnchors -= UpdateTransform;
  185. }
  186. }
  187.  
  188. void Update()
  189. {
  190. //Use keys to ratchet rotation
  191. if (Input.GetKeyDown(KeyCode.Q))
  192. buttonRotation -= RotationRatchet;
  193.  
  194. if (Input.GetKeyDown(KeyCode.E))
  195. buttonRotation += RotationRatchet;
  196. }
  197.  
  198. protected virtual void UpdateController()
  199. {
  200. if (useProfileData)
  201. {
  202. if (InitialPose == null)
  203. {
  204. // Save the initial pose so it can be recovered if useProfileData
  205. // is turned off later.
  206. InitialPose = new OVRPose()
  207. {
  208. position = CameraRig.transform.localPosition,
  209. orientation = CameraRig.transform.localRotation
  210. };
  211. }
  212.  
  213. var p = CameraRig.transform.localPosition;
  214. if (OVRManager.instance.trackingOriginType == OVRManager.TrackingOrigin.EyeLevel)
  215. {
  216. p.y = OVRManager.profile.eyeHeight - (0.5f * Controller.height) + Controller.center.y;
  217. }
  218. else if (OVRManager.instance.trackingOriginType == OVRManager.TrackingOrigin.FloorLevel)
  219. {
  220. p.y = -(0.5f * Controller.height) + Controller.center.y;
  221. }
  222. CameraRig.transform.localPosition = p;
  223. }
  224. else if (InitialPose != null)
  225. {
  226. // Return to the initial pose if useProfileData was turned off at runtime
  227. CameraRig.transform.localPosition = InitialPose.Value.position;
  228. CameraRig.transform.localRotation = InitialPose.Value.orientation;
  229. InitialPose = null;
  230. }
  231.  
  232. CameraHeight = CameraRig.centerEyeAnchor.localPosition.y;
  233.  
  234. if (CameraUpdated != null)
  235. {
  236. CameraUpdated();
  237. }
  238.  
  239. UpdateMovement();
  240.  
  241. Vector3 moveDirection = Vector3.zero;
  242.  
  243. float motorDamp = (1.0f + (Damping * SimulationRate * Time.deltaTime));
  244.  
  245. MoveThrottle.x /= motorDamp;
  246. MoveThrottle.y = (MoveThrottle.y > 0.0f) ? (MoveThrottle.y / motorDamp) : MoveThrottle.y;
  247. MoveThrottle.z /= motorDamp;
  248.  
  249. moveDirection += MoveThrottle * SimulationRate * Time.deltaTime;
  250.  
  251. // Gravity
  252. if (Controller.isGrounded && FallSpeed <= 0)
  253. FallSpeed = ((Physics.gravity.y * (GravityModifier * 0.002f)));
  254. else
  255. FallSpeed += ((Physics.gravity.y * (GravityModifier * 0.002f)) * SimulationRate * Time.deltaTime);
  256.  
  257. moveDirection.y += FallSpeed * SimulationRate * Time.deltaTime;
  258.  
  259.  
  260. if (Controller.isGrounded && MoveThrottle.y <= transform.lossyScale.y * 0.001f)
  261. {
  262. // Offset correction for uneven ground
  263. float bumpUpOffset = Mathf.Max(Controller.stepOffset, new Vector3(moveDirection.x, 0, moveDirection.z).magnitude);
  264. moveDirection -= bumpUpOffset * Vector3.up;
  265. }
  266.  
  267. if (PreCharacterMove != null)
  268. {
  269. PreCharacterMove();
  270. Teleported = false;
  271. }
  272.  
  273. Vector3 predictedXZ = Vector3.Scale((Controller.transform.localPosition + moveDirection), new Vector3(1, 0, 1));
  274.  
  275. // Move contoller
  276. Controller.Move(moveDirection);
  277. Vector3 actualXZ = Vector3.Scale(Controller.transform.localPosition, new Vector3(1, 0, 1));
  278.  
  279. if (predictedXZ != actualXZ)
  280. MoveThrottle += (actualXZ - predictedXZ) / (SimulationRate * Time.deltaTime);
  281. }
  282.  
  283.  
  284.  
  285.  
  286.  
  287. public virtual void UpdateMovement()
  288. {
  289. if (HaltUpdateMovement)
  290. return;
  291.  
  292. if (EnableLinearMovement)
  293. {
  294. bool moveForward = Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow);
  295. bool moveLeft = Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow);
  296. bool moveRight = Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow);
  297. bool moveBack = Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow);
  298.  
  299. bool dpad_move = false;
  300.  
  301. if (OVRInput.Get(OVRInput.Button.DpadUp))
  302. {
  303. moveForward = true;
  304. dpad_move = true;
  305.  
  306. }
  307.  
  308. if (OVRInput.Get(OVRInput.Button.DpadDown))
  309. {
  310. moveBack = true;
  311. dpad_move = true;
  312. }
  313.  
  314. MoveScale = 1.0f;
  315.  
  316. if ((moveForward && moveLeft) || (moveForward && moveRight) ||
  317. (moveBack && moveLeft) || (moveBack && moveRight))
  318. MoveScale = 0.70710678f;
  319.  
  320. // No positional movement if we are in the air
  321. if (!Controller.isGrounded)
  322. MoveScale = 0.0f;
  323.  
  324. MoveScale *= SimulationRate * Time.deltaTime;
  325.  
  326. // Compute this for key movement
  327. float moveInfluence = Acceleration * 0.1f * MoveScale * MoveScaleMultiplier;
  328.  
  329. // Run!
  330. if (dpad_move || Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
  331. moveInfluence *= 2.0f;
  332.  
  333. Quaternion ort = transform.rotation;
  334. Vector3 ortEuler = ort.eulerAngles;
  335. ortEuler.z = ortEuler.x = 0f;
  336. ort = Quaternion.Euler(ortEuler);
  337.  
  338. if (moveForward)
  339. MoveThrottle += ort * (transform.lossyScale.z * moveInfluence * Vector3.forward);
  340. if (moveBack)
  341. MoveThrottle += ort * (transform.lossyScale.z * moveInfluence * BackAndSideDampen * Vector3.back);
  342. if (moveLeft)
  343. MoveThrottle += ort * (transform.lossyScale.x * moveInfluence * BackAndSideDampen * Vector3.left);
  344. if (moveRight)
  345. MoveThrottle += ort * (transform.lossyScale.x * moveInfluence * BackAndSideDampen * Vector3.right);
  346.  
  347.  
  348.  
  349. moveInfluence = Acceleration * 0.1f * MoveScale * MoveScaleMultiplier;
  350.  
  351. #if !UNITY_ANDROID // LeftTrigger not avail on Android game pad
  352. moveInfluence *= 1.0f + OVRInput.Get(OVRInput.Axis1D.PrimaryIndexTrigger);
  353. #endif
  354.  
  355. Vector2 primaryAxis = OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick);
  356.  
  357. // If speed quantization is enabled, adjust the input to the number of fixed speed steps.
  358. if (FixedSpeedSteps > 0)
  359. {
  360. primaryAxis.y = Mathf.Round(primaryAxis.y * FixedSpeedSteps) / FixedSpeedSteps;
  361. primaryAxis.x = Mathf.Round(primaryAxis.x * FixedSpeedSteps) / FixedSpeedSteps;
  362. }
  363.  
  364. if (primaryAxis.y > 0.0f)
  365. MoveThrottle += ort * (primaryAxis.y * transform.lossyScale.z * moveInfluence * Vector3.forward);
  366.  
  367. if (primaryAxis.y < 0.0f)
  368. MoveThrottle += ort * (Mathf.Abs(primaryAxis.y) * transform.lossyScale.z * moveInfluence *
  369. BackAndSideDampen * Vector3.back);
  370.  
  371. if (primaryAxis.x < 0.0f)
  372. MoveThrottle += ort * (Mathf.Abs(primaryAxis.x) * transform.lossyScale.x * moveInfluence *
  373. BackAndSideDampen * Vector3.left);
  374.  
  375. if (primaryAxis.x > 0.0f)
  376. MoveThrottle += ort * (primaryAxis.x * transform.lossyScale.x * moveInfluence * BackAndSideDampen *
  377. Vector3.right);
  378. }
  379.  
  380. if (EnableRotation)
  381. {
  382. Vector3 euler = transform.rotation.eulerAngles;
  383. float rotateInfluence = SimulationRate * Time.deltaTime * RotationAmount * RotationScaleMultiplier;
  384.  
  385. bool curHatLeft = OVRInput.Get(OVRInput.Button.PrimaryShoulder);
  386.  
  387. if (curHatLeft && !prevHatLeft)
  388. euler.y -= RotationRatchet;
  389.  
  390. prevHatLeft = curHatLeft;
  391.  
  392. bool curHatRight = OVRInput.Get(OVRInput.Button.SecondaryShoulder);
  393.  
  394. if (curHatRight && !prevHatRight)
  395. euler.y += RotationRatchet;
  396.  
  397. prevHatRight = curHatRight;
  398.  
  399. euler.y += buttonRotation;
  400. buttonRotation = 0f;
  401.  
  402.  
  403. #if !UNITY_ANDROID || UNITY_EDITOR
  404. if (!SkipMouseRotation)
  405. euler.y += Input.GetAxis("Mouse X") * rotateInfluence * 3.25f;
  406. #endif
  407.  
  408. if (SnapRotation)
  409. {
  410. if (OVRInput.Get(OVRInput.Button.SecondaryThumbstickLeft) ||
  411. (RotationEitherThumbstick && OVRInput.Get(OVRInput.Button.PrimaryThumbstickLeft)))
  412. {
  413. if (ReadyToSnapTurn)
  414. {
  415. euler.y -= RotationRatchet;
  416. ReadyToSnapTurn = false;
  417. }
  418. }
  419. else if (OVRInput.Get(OVRInput.Button.SecondaryThumbstickRight) ||
  420. (RotationEitherThumbstick && OVRInput.Get(OVRInput.Button.PrimaryThumbstickRight)))
  421. {
  422. if (ReadyToSnapTurn)
  423. {
  424. euler.y += RotationRatchet;
  425. ReadyToSnapTurn = false;
  426. }
  427. }
  428. else
  429. {
  430. ReadyToSnapTurn = true;
  431. }
  432. }
  433. else
  434. {
  435. Vector2 secondaryAxis = OVRInput.Get(OVRInput.Axis2D.SecondaryThumbstick);
  436. if (RotationEitherThumbstick)
  437. {
  438. Vector2 altSecondaryAxis = OVRInput.Get(OVRInput.Axis2D.PrimaryThumbstick);
  439. if (secondaryAxis.sqrMagnitude < altSecondaryAxis.sqrMagnitude)
  440. {
  441. secondaryAxis = altSecondaryAxis;
  442. }
  443. }
  444. euler.y += secondaryAxis.x * rotateInfluence;
  445. }
  446.  
  447. transform.rotation = Quaternion.Euler(euler);
  448. }
  449. }
  450.  
  451.  
  452. /// <summary>
  453. /// Invoked by OVRCameraRig's UpdatedAnchors callback. Allows the Hmd rotation to update the facing direction of the player.
  454. /// </summary>
  455. public void UpdateTransform(OVRCameraRig rig)
  456. {
  457. Transform root = CameraRig.trackingSpace;
  458. Transform centerEye = CameraRig.centerEyeAnchor;
  459.  
  460. if (HmdRotatesY && !Teleported)
  461. {
  462. Vector3 prevPos = root.position;
  463. Quaternion prevRot = root.rotation;
  464.  
  465. transform.rotation = Quaternion.Euler(0.0f, centerEye.rotation.eulerAngles.y, 0.0f);
  466.  
  467. root.position = prevPos;
  468. root.rotation = prevRot;
  469. }
  470.  
  471. UpdateController();
  472. if (TransformUpdated != null)
  473. {
  474. TransformUpdated(root);
  475. }
  476. }
  477.  
  478. /// <summary>
  479. /// Jump! Must be enabled manually.
  480. /// </summary>
  481. public bool Jump()
  482. {
  483. if (!Controller.isGrounded)
  484. return false;
  485.  
  486. MoveThrottle += new Vector3(0, transform.lossyScale.y * JumpForce, 0);
  487.  
  488. return true;
  489. }
  490.  
  491. /// <summary>
  492. /// Stop this instance.
  493. /// </summary>
  494. public void Stop()
  495. {
  496. Controller.Move(Vector3.zero);
  497. MoveThrottle = Vector3.zero;
  498. FallSpeed = 0.0f;
  499. }
  500.  
  501. /// <summary>
  502. /// Gets the move scale multiplier.
  503. /// </summary>
  504. /// <param name="moveScaleMultiplier">Move scale multiplier.</param>
  505. public void GetMoveScaleMultiplier(ref float moveScaleMultiplier)
  506. {
  507. moveScaleMultiplier = MoveScaleMultiplier;
  508. }
  509.  
  510. /// <summary>
  511. /// Sets the move scale multiplier.
  512. /// </summary>
  513. /// <param name="moveScaleMultiplier">Move scale multiplier.</param>
  514. public void SetMoveScaleMultiplier(float moveScaleMultiplier)
  515. {
  516. MoveScaleMultiplier = moveScaleMultiplier;
  517. }
  518.  
  519. /// <summary>
  520. /// Gets the rotation scale multiplier.
  521. /// </summary>
  522. /// <param name="rotationScaleMultiplier">Rotation scale multiplier.</param>
  523. public void GetRotationScaleMultiplier(ref float rotationScaleMultiplier)
  524. {
  525. rotationScaleMultiplier = RotationScaleMultiplier;
  526. }
  527.  
  528. /// <summary>
  529. /// Sets the rotation scale multiplier.
  530. /// </summary>
  531. /// <param name="rotationScaleMultiplier">Rotation scale multiplier.</param>
  532. public void SetRotationScaleMultiplier(float rotationScaleMultiplier)
  533. {
  534. RotationScaleMultiplier = rotationScaleMultiplier;
  535. }
  536.  
  537. /// <summary>
  538. /// Gets the allow mouse rotation.
  539. /// </summary>
  540. /// <param name="skipMouseRotation">Allow mouse rotation.</param>
  541. public void GetSkipMouseRotation(ref bool skipMouseRotation)
  542. {
  543. skipMouseRotation = SkipMouseRotation;
  544. }
  545.  
  546. /// <summary>
  547. /// Sets the allow mouse rotation.
  548. /// </summary>
  549. /// <param name="skipMouseRotation">If set to <c>true</c> allow mouse rotation.</param>
  550. public void SetSkipMouseRotation(bool skipMouseRotation)
  551. {
  552. SkipMouseRotation = skipMouseRotation;
  553. }
  554.  
  555. /// <summary>
  556. /// Gets the halt update movement.
  557. /// </summary>
  558. /// <param name="haltUpdateMovement">Halt update movement.</param>
  559. public void GetHaltUpdateMovement(ref bool haltUpdateMovement)
  560. {
  561. haltUpdateMovement = HaltUpdateMovement;
  562. }
  563.  
  564. /// <summary>
  565. /// Sets the halt update movement.
  566. /// </summary>
  567. /// <param name="haltUpdateMovement">If set to <c>true</c> halt update movement.</param>
  568. public void SetHaltUpdateMovement(bool haltUpdateMovement)
  569. {
  570. HaltUpdateMovement = haltUpdateMovement;
  571. }
  572.  
  573. /// <summary>
  574. /// Resets the player look rotation when the device orientation is reset.
  575. /// </summary>
  576. public void ResetOrientation()
  577. {
  578. if (HmdResetsY && !HmdRotatesY)
  579. {
  580. Vector3 euler = transform.rotation.eulerAngles;
  581. euler.y = InitialYRotation;
  582. transform.rotation = Quaternion.Euler(euler);
  583. }
  584. }
  585. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement