SW 중심대학 OSS GIT 서버 새로운 리포
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
3.6 KiB

5 years ago
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.XR;
  5. using UnityEngine.XR.Interaction.Toolkit;
  6. public class ContinuousMovement : MonoBehaviour
  7. {
  8. public float gravity = -9.81f; //중력 상수
  9. public float speed = 1f;
  10. public float additionalHeight = 0.2f; //눈~정수리 위까지의 추가 키
  11. public XRNode inputSource; //인풋을 가져올 XRNode => Left Hand로 설정
  12. public LayerMask groundLayer; //히트 체크할 땅의 레이어
  13. private float fallingSpeed; //떨어지는 속도
  14. private Vector2 inputAxis; //조이스틱 인풋값
  15. private CharacterController character; //이동용 컴포넌트
  16. private XRRig rig; //카메라 바라보는 방향 가져오기 위해 레퍼런스 가져옴
  17. // Start is called before the first frame update
  18. void Start()
  19. {
  20. character = GetComponent<CharacterController>();
  21. rig = GetComponent<XRRig>();
  22. }
  23. // Update is called once per frame
  24. void Update()
  25. {
  26. //XRNode로 device가져와서 인풋값 받기
  27. InputDevice device = InputDevices.GetDeviceAtXRNode(inputSource);
  28. device.TryGetFeatureValue(CommonUsages.primary2DAxis, out inputAxis);
  29. }
  30. //CharacterController는 물리적으로 반응하며 움직이기 떄문에 FixedUpdate에서 처리해줘야 함
  31. private void FixedUpdate() //0.02 * 50 = 1
  32. {
  33. CapsuleFollowHeadset();
  34. //※사원수를 쓰는 이유 : https://hoodymong.tistory.com/3
  35. //카메라의 y 앵글값(=Yaw)을 사원수(Quaternion)으로 변환
  36. Quaternion headYaw = Quaternion.Euler(0f, rig.cameraGameObject.transform.eulerAngles.y, 0f);
  37. //Quaternion x Vector3 하면 회전
  38. Vector3 direction = headYaw * new Vector3(inputAxis.x, 0f, inputAxis.y);
  39. character.Move(direction * Time.fixedDeltaTime * speed);
  40. //중력 적용 : 발이 땅에 붙어있지 않을 때만 하강 속도가 증가하도록
  41. bool isGrounded = CheckIfGrounded();
  42. if (isGrounded)
  43. fallingSpeed = 0f;
  44. else
  45. fallingSpeed += gravity * Time.fixedDeltaTime;
  46. character.Move(Vector3.up * fallingSpeed * Time.fixedDeltaTime);
  47. }
  48. //발이 땅에 붙었는지?를 리턴하는 함수
  49. private bool CheckIfGrounded()
  50. {
  51. Vector3 rayStart = transform.TransformPoint(character.center); //CharacterController의 중심점을 월드 스페이스 변환
  52. float rayLength = character.center.y + 0.01f; //광선 길이는 CC의 키/2 보다 살짝만 더 길게해서 발 밑을 확실히 체크하도록 해줌
  53. bool hasHit = Physics.SphereCast(rayStart, character.radius, Vector3.down, out RaycastHit hitInfo, rayLength, groundLayer);
  54. return hasHit;
  55. }
  56. //캐릭터 컨트롤러의 캡슐이 내 머리 위치 따라오도록 설정
  57. void CapsuleFollowHeadset()
  58. {
  59. //카메라의 위치를 자기 자신 기준 local 좌표로 보정하여 저장
  60. Vector3 capsuleCenter = transform.InverseTransformPoint(rig.cameraGameObject.transform.position);
  61. //Capsule의 높이를 rig의 높이 + 약간의 여유값에 맞춰줌
  62. character.height = rig.cameraInRigSpaceHeight + additionalHeight;
  63. //수평(x, z) 좌표는 capsuleCenter를 따라가고, y는 character.height의 절반으로 해서 발을 땅에 붙이도록 해줌
  64. character.center = new Vector3(capsuleCenter.x, character.height / 2f, capsuleCenter.z);
  65. }
  66. }