MoveController.cs 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using System.Security.Cryptography;
  2. using UnityEngine;
  3. using UnityEngine.EventSystems;
  4. public class MoveController : MonoBehaviour
  5. {
  6. public float jumpHeight = 2.0f;
  7. public float gravity = -9.8f;
  8. private float speed = 6f;
  9. private float verticalVelocity = 0.0f;
  10. private bool isGrounded = false;
  11. private float groundCheckDistance = 0.01f;
  12. private int groundLayer = ~(1 << 6);
  13. public PlayerInputComponent playerInput;
  14. private AnimatorController controller;
  15. private Vector3 move;
  16. private Vector3 gravityMove;
  17. private Vector3 initPos;
  18. private float offset;
  19. public Transform camera;
  20. private float angleX;
  21. private float angleY;
  22. public enum PlayerState
  23. {
  24. Ground,
  25. JumpUp,
  26. JumpDown,
  27. }
  28. private CharacterController character;
  29. public PlayerState state;
  30. // Start is called before the first frame update
  31. void Start()
  32. {
  33. controller = GetComponent<AnimatorController>();
  34. character = GetComponent<CharacterController>();
  35. playerInput=GetComponent<PlayerInputComponent>();
  36. angleX = Vector3.Angle(Vector3.right, camera.right);
  37. angleY = Vector3.Angle(Vector3.up, camera.up);
  38. character.enabled = true;
  39. }
  40. // Update is called once per frame
  41. void Update()
  42. {
  43. if (StepManager.isFaceBuidling) playerInput.InputReset();
  44. /* if(!StepManager.isFaceBuidling) */
  45. CharacterMovement();
  46. }
  47. /// <summary>
  48. /// 角色移动旋转总逻辑
  49. /// </summary>
  50. void CharacterMovement()
  51. {
  52. // 检测是否在地面上
  53. isGrounded = IsGrounded();
  54. //Debug.Log(isGrounded);
  55. if (isGrounded)
  56. {
  57. // 按下空格键触发跳跃
  58. if (playerInput.JumpInput)
  59. {
  60. state = PlayerState.JumpUp;
  61. Jump();
  62. controller.jump = true;
  63. }
  64. }
  65. else
  66. {
  67. if (state != PlayerState.JumpUp)
  68. {
  69. state = PlayerState.JumpDown;
  70. }
  71. }
  72. if (isGrounded && state == PlayerState.JumpDown)
  73. {
  74. state = PlayerState.Ground;
  75. }
  76. move = Vector3.zero;
  77. if (state != PlayerState.Ground)
  78. {
  79. // 应用重力
  80. ApplyGravity();
  81. }
  82. //Debug.Log(playerInput.MoveInput);
  83. move +=
  84. new Vector3(playerInput.MoveInput.x, 0, playerInput.MoveInput.y)
  85. * Time.deltaTime
  86. * speed;
  87. // 移动物体
  88. Move();
  89. UpdateControlRotation();
  90. }
  91. void Jump()
  92. {
  93. // 计算跳跃速度以达到指定的跳跃高度
  94. verticalVelocity = Mathf.Sqrt(-2.0f * gravity * jumpHeight);
  95. }
  96. void ApplyGravity()
  97. {
  98. // 应用重力以模拟物体的垂直运动
  99. verticalVelocity += gravity * Time.deltaTime;
  100. // 根据垂直速度移动物体
  101. if (verticalVelocity < 0.1f && verticalVelocity > -0.1f && state == PlayerState.JumpUp)
  102. {
  103. state = PlayerState.JumpDown;
  104. }
  105. gravityMove = new Vector3(0, verticalVelocity * Time.deltaTime, 0);
  106. }
  107. void Move()
  108. {
  109. //Debug.Log(playerInput.name + "****" + move);
  110. //var camRot = new Vector3(0, camera.eulerAngles.y, 0);
  111. if (playerInput.MoveInput != Vector2.zero)
  112. {
  113. Vector3 dir = Vector3.zero;
  114. //Debug.Log(playerInput.MoveInput);
  115. if (playerInput.MoveInput.x > 0)
  116. {
  117. dir = Vector3.ProjectOnPlane(camera.right, Vector3.up);
  118. }
  119. if (playerInput.MoveInput.x < 0)
  120. {
  121. dir += Vector3.ProjectOnPlane(-camera.right, Vector3.up);
  122. }
  123. if (playerInput.MoveInput.y > 0)
  124. {
  125. dir += Vector3.ProjectOnPlane(camera.forward, Vector3.up);
  126. }
  127. if (playerInput.MoveInput.y < 0)
  128. {
  129. dir += Vector3.ProjectOnPlane(-camera.forward, Vector3.up);
  130. }
  131. //Debug.Log(dir);
  132. Vector3 targetDir = Vector3.RotateTowards(
  133. transform.forward,
  134. //camera.forward.ProjectOntoPlane(Vector3.up),
  135. dir,
  136. 10,
  137. 0f
  138. );
  139. transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetDir),Time.deltaTime * 15f);
  140. //var a = Vector3.Angle(transform.forward.normalized, playerInput.MoveInput.normalized);
  141. //Quaternion r = Quaternion.Euler(0, a, 0);
  142. //transform.eulerAngles = r * transform.eulerAngles;
  143. }
  144. //var m = move.magnitude * camera.forward + gravityMove;
  145. //Debug.Log(move + "*******" + "************" + m);
  146. var angle = AngleSigned(
  147. Vector3.forward,
  148. Vector3.ProjectOnPlane(camera.forward, Vector3.up),
  149. transform.up
  150. );
  151. Quaternion rot = Quaternion.Euler(0, angle, 0);
  152. //Vector3 move2 = camera.transform.TransformDirection(move);
  153. controller.speed = move.magnitude * 300;
  154. character.Move(rot * move + gravityMove);
  155. camera.position= character.transform.position+new Vector3(0,1.148f,0);
  156. }
  157. public static float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n)
  158. {
  159. return Mathf.Atan2(Vector3.Dot(n, Vector3.Cross(v1, v2)), Vector3.Dot(v1, v2))
  160. * Mathf.Rad2Deg;
  161. }
  162. private Vector3 pointBottom;
  163. private Vector3 pointTop;
  164. private float radius = 0.5f;
  165. private Collider[] colliders;
  166. private float LerpValue = 0.05f;
  167. bool IsGrounded()
  168. {
  169. // 在这里你可以添加检测物体是否在地面上的逻辑
  170. // 例如射线检测、碰撞器检测等
  171. radius = character.radius * 0.9f;
  172. pointBottom = transform.position + transform.up * radius - transform.up * 0.1f;
  173. pointTop = transform.position + transform.up * character.height - transform.up * radius;
  174. colliders = Physics.OverlapCapsule(pointBottom, pointTop, radius, groundLayer);
  175. Debug.DrawLine(pointBottom, pointTop, Color.red);
  176. if (colliders.Length != 0)
  177. {
  178. return true;
  179. }
  180. else
  181. {
  182. return false;
  183. }
  184. }
  185. private void UpdateControlRotation()
  186. {
  187. if (playerInput.touch0Input != Vector2.zero && playerInput.MoveInput == Vector2.zero && !EventSystem.current.IsPointerOverGameObject())
  188. {
  189. //camera.eulerAngles += (new Vector3(playerInput.touch0Input.y, playerInput.touch0Input.x, 0)) * 0.1f;
  190. angleX += playerInput.touch0Input.x * 10 * Time.fixedDeltaTime;
  191. angleY -= playerInput.touch0Input.y * 10 * Time.fixedDeltaTime;
  192. angleY = angleClamp(angleY, -10, 60);//相机旋转角度限制
  193. //使用插值平滑旋转
  194. camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5);
  195. }
  196. if (playerInput.touch1Input != Vector2.zero && !EventSystem.current.IsPointerOverGameObject())
  197. {
  198. angleX += playerInput.touch1Input.x * 10 * Time.fixedDeltaTime;
  199. angleY -= playerInput.touch1Input.y * 10 * Time.fixedDeltaTime;
  200. angleY = angleClamp(angleY, -10, 60);//相机旋转角度限制
  201. //使用插值平滑旋转
  202. camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5);
  203. }
  204. angleX += playerInput.CameraInput.x * 10 * Time.fixedDeltaTime;
  205. angleY -= playerInput.CameraInput.y * 10 * Time.fixedDeltaTime;
  206. angleY = angleClamp(angleY, -10, 60);//相机旋转角度限制
  207. //使用插值平滑旋转
  208. camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5);
  209. }
  210. private static float angleClamp(float angle, float min, float max)
  211. {//一个限制角度最大最小值的方法
  212. if (angle < -360)
  213. angle += 360;
  214. if (angle > 360)
  215. angle -= 360;
  216. return Mathf.Clamp(angle, min, max);
  217. }
  218. }