MoveController.cs 7.5 KB

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