using UnityEngine; using UnityEngine.EventSystems; using static UnityEditor.ShaderGraph.Internal.KeywordDependentCollection; 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 bool isGrounded = false; private bool hasLand = false; private bool isBlock = false; private AnimatorController controller; private Transform head; private Transform m_camera; private Vector3 move; private Vector3 gravityMove; private Vector3 lastMove; private Vector3 camInitPos; private RaycastHit hit; private Vector3 colliderDir; 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; } // Update is called once per frame void Update() { if (StepManager.isFaceBuidling) playerInput.InputReset(); CharacterMovement(); } /// /// ��ɫ�ƶ���ת���߼� /// void CharacterMovement() { if (hasLand) { jumpTime += Time.deltaTime; } // ����Ƿ��ڵ����� //isGrounded = IsGrounded(); 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(); CameraLimitation(); 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() { if (playerInput.MoveInput != Vector2.zero) { Vector3 dir = Vector3.zero; //Debug.Log(playerInput.MoveInput); if (playerInput.MoveInput.x > 0) { dir = Vector3.ProjectOnPlane(camRoot.right, Vector3.up); } if (playerInput.MoveInput.x < 0) { dir += Vector3.ProjectOnPlane(-camRoot.right, Vector3.up); } if (playerInput.MoveInput.y > 0) { dir += Vector3.ProjectOnPlane(camRoot.forward, Vector3.up); } if (playerInput.MoveInput.y < 0) { dir += Vector3.ProjectOnPlane(-camRoot.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(camRoot.forward, Vector3.up), transform.up ); Quaternion rot = Quaternion.Euler(0, angle, 0); //Vector3 move2 = camera.transform.TransformDirection(move); //Debug.Log(move.magnitude + "***********" + gravityMove.magnitude); //var m = move * 0.1f + lastMove * 0.9f; var rm = rot * move; if (gravityMove != Vector3.zero) { rm *= 2.5f; } rm = rm * 0.1f + lastMove * 0.9f; //if (state == PlayerState.JumpDown) //{ // character.Move(-colliderDir * Time.deltaTime); //} character.Move(rm + gravityMove); lastMove = rm; controller.speed = rm.magnitude * 300; 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; //if (Physics.Raycast(ray, out temphit, 10f)) //{ // if (temphit.collider.name != "Main Camera") // { // isBlock = true; // hit = temphit; // m_camera.position = Vector3.Lerp(m_camera.position, hit.point, 0.1f); // } // else // { // m_camera.localPosition = Vector3.Lerp(m_camera.localPosition, camInitPos, 0.5f); // } // Debug.Log(temphit.collider.name); //} //if (isBlock) //{ // ////������ת��ͷ���� // //if (finalAngle > 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; m_camera.localPosition = camInitPos + new Vector3(0, 0, z); } else { m_camera.localPosition = Vector3.Lerp(m_camera.localPosition, camInitPos, 0.5f); } //} } }