123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263 |
- 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<AnimatorController>();
- character = GetComponent<CharacterController>();
- playerInput=GetComponent<PlayerInputComponent>();
- 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();
- }
- /// <summary>
- /// 角色移动旋转总逻辑
- /// </summary>
- 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);
- }
- }
|