using System.Security.Cryptography; using UnityEngine; using UnityEngine.EventSystems; public class MoveController : MonoBehaviour { public PlayerInputComponent playerInput; public Transform camera; public float jumpHeight = 2.0f; public float gravity = -13.524f; private int groundLayer = ~(1 << 6); private float speed = 5f; private float verticalVelocity = 0.0f; private float angleX; private float angleY; private float jumpInterval = 0.5f; private float jumpTime = 0.5f; private bool isGrounded = false; private bool hasLand = false; private AnimatorController controller; private Vector3 move; private Vector3 gravityMove; public enum PlayerState { Ground, JumpUp, JumpDown, } private CharacterController character; public PlayerState state; // Start is called before the first frame update void Start() { controller = GetComponent(); character = GetComponent(); playerInput=GetComponent(); angleX = Vector3.Angle(Vector3.right, camera.right); angleY = Vector3.Angle(Vector3.up, camera.up); character.enabled = true; } // Update is called once per frame void Update() { if (StepManager.isFaceBuidling) playerInput.InputReset(); CharacterMovement(); } /// /// 角色移动旋转总逻辑 /// void CharacterMovement() { if (hasLand) { jumpTime += Time.deltaTime; } // 检测是否在地面上 isGrounded = IsGrounded(); //Debug.Log(isGrounded); if (isGrounded) { // 按下空格键触发跳跃 if (playerInput.JumpInput) { //state = PlayerState.JumpUp; //Jump(); //controller.jump = true; //jumpTime = 0; //hasLand = false; if (jumpTime >= jumpInterval) { state = PlayerState.JumpUp; Jump(); controller.jump = true; jumpTime = 0; hasLand = false; } } } else { if (state != PlayerState.JumpUp) { state = PlayerState.JumpDown; } } if (isGrounded && state == PlayerState.JumpDown) { state = PlayerState.Ground; hasLand = true; } move = Vector3.zero; if (state != PlayerState.Ground) { // 应用重力 ApplyGravity(); } //Debug.Log(playerInput.MoveInput); move += new Vector3(playerInput.MoveInput.x, 0, playerInput.MoveInput.y) * Time.deltaTime * speed; // 移动物体 Move(); UpdateControlRotation(); } void Jump() { // 计算跳跃速度以达到指定的跳跃高度 verticalVelocity = Mathf.Sqrt(-2.0f * gravity * jumpHeight); } void ApplyGravity() { // 应用重力以模拟物体的垂直运动 verticalVelocity += gravity * Time.deltaTime; // 根据垂直速度移动物体 if (verticalVelocity < 0.1f && verticalVelocity > -0.1f && state == PlayerState.JumpUp) { state = PlayerState.JumpDown; } gravityMove = new Vector3(0, verticalVelocity * Time.deltaTime, 0); } void Move() { //Debug.Log(playerInput.name + "****" + move); //var camRot = new Vector3(0, camera.eulerAngles.y, 0); if (playerInput.MoveInput != Vector2.zero) { Vector3 dir = Vector3.zero; //Debug.Log(playerInput.MoveInput); if (playerInput.MoveInput.x > 0) { dir = Vector3.ProjectOnPlane(camera.right, Vector3.up); } if (playerInput.MoveInput.x < 0) { dir += Vector3.ProjectOnPlane(-camera.right, Vector3.up); } if (playerInput.MoveInput.y > 0) { dir += Vector3.ProjectOnPlane(camera.forward, Vector3.up); } if (playerInput.MoveInput.y < 0) { dir += Vector3.ProjectOnPlane(-camera.forward, Vector3.up); } //Debug.Log(dir); Vector3 targetDir = Vector3.RotateTowards( transform.forward, //camera.forward.ProjectOntoPlane(Vector3.up), dir, 10, 0f ); transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetDir),Time.deltaTime * 15f); //var a = Vector3.Angle(transform.forward.normalized, playerInput.MoveInput.normalized); //Quaternion r = Quaternion.Euler(0, a, 0); //transform.eulerAngles = r * transform.eulerAngles; } //var m = move.magnitude * camera.forward + gravityMove; //Debug.Log(move + "*******" + "************" + m); var angle = AngleSigned( Vector3.forward, Vector3.ProjectOnPlane(camera.forward, Vector3.up), transform.up ); Quaternion rot = Quaternion.Euler(0, angle, 0); //Vector3 move2 = camera.transform.TransformDirection(move); controller.speed = move.magnitude * 300; character.Move(rot * move + gravityMove); camera.position= character.transform.position+new Vector3(0,1.148f,0); } public static float AngleSigned(Vector3 v1, Vector3 v2, Vector3 n) { return Mathf.Atan2(Vector3.Dot(n, Vector3.Cross(v1, v2)), Vector3.Dot(v1, v2)) * Mathf.Rad2Deg; } private Vector3 pointBottom; private Vector3 pointTop; private float radius = 0.5f; private Collider[] colliders; private float LerpValue = 0.05f; bool IsGrounded() { // 在这里你可以添加检测物体是否在地面上的逻辑 // 例如射线检测、碰撞器检测等 radius = character.radius * 0.9f; pointBottom = transform.position + transform.up * radius - transform.up * 0.1f; pointTop = transform.position + transform.up * character.height - transform.up * radius; colliders = Physics.OverlapCapsule(pointBottom, pointTop, radius, groundLayer); Debug.DrawLine(pointBottom, pointTop, Color.red); if (colliders.Length != 0) { return true; } else { return false; } } private void UpdateControlRotation() { if (playerInput.touch0Input != Vector2.zero && playerInput.MoveInput == Vector2.zero && !EventSystem.current.IsPointerOverGameObject()) { //camera.eulerAngles += (new Vector3(playerInput.touch0Input.y, playerInput.touch0Input.x, 0)) * 0.1f; angleX += playerInput.touch0Input.x * 10 * Time.fixedDeltaTime; angleY -= playerInput.touch0Input.y * 10 * Time.fixedDeltaTime; angleY = angleClamp(angleY, -1, 60);//相机旋转角度限制 //使用插值平滑旋转 camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5); } if (playerInput.touch1Input != Vector2.zero && !EventSystem.current.IsPointerOverGameObject()) { angleX += playerInput.touch1Input.x * 10 * Time.fixedDeltaTime; angleY -= playerInput.touch1Input.y * 10 * Time.fixedDeltaTime; angleY = angleClamp(angleY, -1, 60);//相机旋转角度限制 //使用插值平滑旋转 camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5); } angleX += playerInput.CameraInput.x * 10 * Time.fixedDeltaTime; angleY -= playerInput.CameraInput.y * 10 * Time.fixedDeltaTime; angleY = angleClamp(angleY, -1, 60);//相机旋转角度限制 //使用插值平滑旋转 camera.rotation = Quaternion.Lerp(camera.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 5); } private static float angleClamp(float angle, float min, float max) {//一个限制角度最大最小值的方法 if (angle < -360) angle += 360; if (angle > 360) angle -= 360; return Mathf.Clamp(angle, min, max); } }