Estoy creando un juego en el que el jugador puede ser controlado usando la entrada del mouse, usando un clic para mover la lógica a través de un agente de navegación.
Para permitir que el jugador salte, también comencé a usar un CharacterController que debería ayudar a administrar al jugador. Mi problema es que no puedo averiguar dónde poner la lógica de salto. Todas las referencias que encontré están relacionadas con el controlador de caracteres sin el agente navmesh.
Puedo deshacerme del CharacterController si es necesario, pero el NavMeshAgent tiene que quedarse.
Aquí hay un código de trabajo que permite caminar. ¿Me pueden ayudar con la lógica de salto?
private NavMeshAgent _agent; private CharacterController _characterController; private Vector3 _desVelocity; private void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo)) { _agent.destination = hitInfo.point; } } var currMovementDirection = _desVelocity.normalized * currentSpeed; if (_agent.remainingDistance > _agent.stoppingDistance) { _desVelocity = _agent.desiredVelocity; _characterController.Move(currMovementDirection * Time.deltaTime); } }Puede lograr esto usando un Rigidbody en lugar de un CharacterController . El truco es que necesitas deshabilitar NavMeshAgent para poder saltar.
Opcionalmente, establece el destino donde se encuentra en el momento del salto, de modo que el agente no continúe con la simulación mientras se produce el salto.
Con la detección de colisiones, vuelve a encender el NavMeshAgent una vez que aterriza.
public class PlayerMovement : MonoBehaviour { private Camera cam; private NavMeshAgent agent; private Rigidbody rigidbody; public bool grounded = true; void Start() { cam = Camera.main; agent = GetComponent<NavMeshAgent>(); rigidbody = GetComponent<Rigidbody>(); } void Update() { // clicking on the nav mesh, sets the destination of the agent and off he goes if (Input.GetMouseButtonDown(0) && (!agent.isStopped)) { Ray ray = cam.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { agent.SetDestination(hit.point); } } // when you want to jump if (Input.GetKeyDown(KeyCode.Space) && grounded) { grounded = false; if (agent.enabled) { // set the agents target to where you are before the jump // this stops her before she jumps. Alternatively, you could // cache this value, and set it again once the jump is complete // to continue the original move agent.SetDestination(transform.position); // disable the agent agent.updatePosition = false; agent.updateRotation = false; agent.isStopped = true; } // make the jump rigidbody.isKinematic = false; rigidbody.useGravity = true; rigidbody.AddRelativeForce(new Vector3(0, 5f, 0), ForceMode.Impulse); } } /// <summary> /// Check for collision back to the ground, and re-enable the NavMeshAgent /// </summary> private void OnCollisionEnter(Collision collision) { if (collision.collider != null && collision.collider.tag == "Ground") { if (!grounded) { if (agent.enabled) { agent.updatePosition = true; agent.updateRotation = true; agent.isStopped = false; } rigidbody.isKinematic = true; rigidbody.useGravity = false; grounded = true; } } } }La lógica de salto debe estar dentro del método Update() ya que queremos que la altura se calcule en cada fotograma.
void Update() { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray.origin, ray.direction, out RaycastHit hitInfo)) { _agent.destination = hitInfo.point; } } var currMovementDirection = _desVelocity.normalized * currentSpeed; groundedPlayer = _characterController.isGrounded; if (groundedPlayer && currMovementDirection.y < 0) { currMovementDirection.y = 0f; } // Changes the height position of the player.. if (Input.GetButtonDown("Jump") && groundedPlayer) { currMovementDirection.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue); } currMovementDirection.y += gravityValue * Time.deltaTime; if (_agent.remainingDistance > _agent.stoppingDistance) { _desVelocity = _agent.desiredVelocity; _characterController.Move(currMovementDirection * Time.deltaTime); } }Consulte los documentos oficiales aquí