MoveController.cs 8.7 KB

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