using UnityEngine; using UnityEngine.EventSystems; public class MoveController : MonoBehaviour { public PlayerInputComponent playerInput; public Transform camRoot; 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 float oriDistance; private bool isGrounded = false; private bool hasLand = false; private AnimatorController controller; private Transform head; private Transform m_camera; private Vector3 move; private Vector3 gravityMove; private Vector3 lastMove; private Vector3 camInitPos; 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, camRoot.right); angleY = Vector3.Angle(Vector3.up, camRoot.up); character.enabled = true; head = transform.Find("Head"); m_camera = camRoot.transform.Find("Main Camera"); camInitPos = m_camera.localPosition; oriDistance = Vector3.Distance(head.position, m_camera.position - m_camera.forward * 2); } // Update is called once per frame void Update() { if (StepManager.isFaceBuidling) playerInput.InputReset(); CharacterMovement(); } /// /// ��ɫ�ƶ���ת���߼� /// void CharacterMovement() { if (hasLand) { jumpTime += Time.deltaTime; } // ����Ƿ��ڵ����� //isGrounded = IsGrounded(); isGrounded = character.isGrounded || IsGrounded(); if (isGrounded && state == PlayerState.JumpDown) { verticalVelocity = 0; state = PlayerState.Ground; hasLand = true; } //Debug.Log(isGrounded); if (state == PlayerState.Ground) { // ���¿ո��������Ծ 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; } } } if (!isGrounded && state != PlayerState.JumpUp) { state = PlayerState.JumpDown; } move = Vector3.zero; if (state != PlayerState.Ground) { // Ӧ������ ApplyGravity(); } else { gravityMove = new Vector3(0, 0, 0); } 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) { //Debug.Log("*************"); state = PlayerState.JumpDown; } //Debug.Log(verticalVelocity * 100); gravityMove = new Vector3(0, verticalVelocity * Time.deltaTime, 0); } void Move() { CameraLimitation(); if (playerInput.MoveInput != Vector2.zero) { Vector3 dir = Vector3.zero; if (playerInput.MoveInput.x > 0) { dir = Vector3.ProjectOnPlane( camRoot.right * Mathf.Abs(playerInput.MoveInput.x), Vector3.up ); } if (playerInput.MoveInput.x < 0) { dir += Vector3.ProjectOnPlane( -camRoot.right * Mathf.Abs(playerInput.MoveInput.x), Vector3.up ); } if (playerInput.MoveInput.y > 0) { dir += Vector3.ProjectOnPlane( camRoot.forward * Mathf.Abs(playerInput.MoveInput.y), Vector3.up ); } if (playerInput.MoveInput.y < 0) { dir += Vector3.ProjectOnPlane( -camRoot.forward * Mathf.Abs(playerInput.MoveInput.y), 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 angle = AngleSigned( Vector3.forward, Vector3.ProjectOnPlane(camRoot.forward, Vector3.up), transform.up ); Quaternion rot = Quaternion.Euler(0, angle, 0); var rm = rot * move; if (gravityMove != Vector3.zero) { rm *= 2.5f; } rm = rm * 0.1f + lastMove * 0.9f; controller.speed = rm.magnitude * 300; character.Move(rm + gravityMove); lastMove = rm; camRoot.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; bool IsGrounded() { // �������������Ӽ�������Ƿ��ڵ����ϵ��߼� // �������߼�⡢��ײ������ var pos = transform.position; radius = character.radius * 0.9f; pointBottom = pos + transform.up * radius - transform.up * 0.1f; pointTop = pos + 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, -45, 60); //�����ת�Ƕ����� //ʹ�ò�ֵƽ����ת camRoot.rotation = Quaternion.Lerp( camRoot.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 100 ); } 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, -45, 60); //�����ת�Ƕ����� //ʹ�ò�ֵƽ����ת camRoot.rotation = Quaternion.Lerp( camRoot.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 100 ); } angleX += playerInput.CameraInput.x * 10 * Time.fixedDeltaTime; angleY -= playerInput.CameraInput.y * 10 * Time.fixedDeltaTime; angleY = angleClamp(angleY, -45, 60); //�����ת�Ƕ����� //ʹ�ò�ֵƽ����ת camRoot.rotation = Quaternion.Lerp( camRoot.rotation, Quaternion.Euler(angleY, angleX, 0), Time.fixedDeltaTime * 10 ); } 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); } /// /// �����˳ƾ�ͷ�����ƶ� /// private void CameraLimitation() { float cosAngle = Vector3.Dot(m_camera.forward, Vector3.up); float angleRad = Mathf.Asin(cosAngle); float angleDeg = Mathf.Rad2Deg * angleRad; float sign = Mathf.Sign( Vector3.Dot(Vector3.Cross(m_camera.forward, Vector3.up), Vector3.up) ); float finalAngle = sign * angleDeg; //float moveDistance = Mathf.Sin(Mathf.Deg2Rad * Mathf.Clamp(finalAngle, 0f, 10)) * 2; float z, obsDistance = 0, camDistance = 0; //Debug.Log(finalAngle); //射线检测是否有障碍物 Ray ray = new Ray(head.position, m_camera.position - head.position); RaycastHit[] temphit; RaycastHit hit; var cos = Physics.Raycast(ray, out hit, oriDistance, ~(1 << 6 | 1 << 18)); if (cos) { Debug.Log(hit.collider.name); m_camera.position = Vector3.Lerp(m_camera.position, hit.point, 0.5f); } else { m_camera.localPosition = Vector3.Lerp(m_camera.localPosition, camInitPos, 0.5f); } //RaycastHit[] temphit; //var cos = Physics.RaycastAll(head.position, m_camera.position - head.position, oriDistance, ~(1 << 6)); //if (cos.Length>0) //{ // //Debug.Log(temphit.collider.name); // //m_camera.position = Vector3.Lerp(m_camera.position, temphit.point, 0.5f); // RaycastHit hit = cos[0]; // float dis = 0; // for (int i = 1; i 1) //{ // z = finalAngle * 0.1f; // camDistance = Vector3.Distance(camInitPos + new Vector3(0, 0, z),head.position); // Debug.DrawLine(temphit.point, head.position, Color.red); // Debug.DrawLine(camInitPos + new Vector3(0, 0, z), head.position, Color.blue); // Debug.Log(hit.collider.name+"))"+obsDistance + " // " + camDistance); // //if (obsDistance < camDistance && obsDistance > 0) // //{ // // m_camera.position = Vector3.Lerp(m_camera.position, hit.point, 0.1f); // //} // //else // //{ // // m_camera.localPosition = camInitPos + new Vector3(0, 0, z); // //} //} //else // { // m_camera.position = Vector3.Lerp(m_camera.position, hit.point, 0.5f); // } //} //else //{ //旋转 if (finalAngle > 1) { z = finalAngle * 0.1f; var pos = camInitPos + new Vector3(0, 0, z); var dis1 = Vector3.Distance(head.position, pos); var dis2 = Vector3.Distance(m_camera.position, head.position); if (!cos) m_camera.localPosition = camInitPos + new Vector3(0, 0, z); } if (m_camera.localPosition.z > -0.4f) { m_camera.localPosition = new Vector3( m_camera.localPosition.x, m_camera.localPosition.y, -0.4f ); } //else //{ // m_camera.localPosition = Vector3.Lerp(m_camera.localPosition, camInitPos, 0.5f); //} //} } }