Noticias

¡RECUERDA QUE SI ERES UN NUEVO USUARIO, DEBES PRESENTARTE PARA PODER PUBLICAR MENSAJES! | TENEMOS CANAL OFICIAL DE TELEGRAM: t.me/unity3dspain

[AYUDA] Corregir control del player en el aire

Iniciado por Null, Septiembre 24, 2016, 04:14:31 PM

Tema anterior - Siguiente tema
Hi.
 
Tengo hecho el salto de mi player,

pero éste aún tiene control de movimiento estando en el aire,

y la verdad no busco eso.

 
 
Lo que busco en su lugar es que si está caminando en una dirección,

y entonces salta, que no pueda moverse en el aire hacia los lados,

o por lo menos hacer que pueda moverse muy poco, para que el salto

no sea TAN rígido.
 


He probado con poner todo el código que hace que mi player camine

dentro de un "if (isGrounded) ...", pero no me funcionó.
 
 
 
Adiciono las partes del código que uso para hacer

que mi player camine, y salte, aquí abajo.

Estoy usando un CharacterController.
 
Nótese que en este código todavía no intenté corregir dicho problema:
 

   void Caminar()
    {
        float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
        float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
        _gravedad += Physics.gravity.y * Time.deltaTime;
        Vector3 _velocidad = new Vector3(_movHorizontal, _gravedad, _movVertical);
        _velocidad = transform.rotation * _velocidad;
        _cc.Move(_velocidad * Time.deltaTime);
    }
    void Saltar()
    {
        if (_cc.isGrounded)
        {
            _estaEnElSuelo = true;
            _puedeSaltar = true;
            _puedeCorrer = true;
        }
        else
        {
            _estaEnElSuelo = false;
            _puedeSaltar = false;
            _puedeCorrer = false;
        }
        if (_puedeSaltar)
        {
            if (Input.GetButtonDown("Jump"))
            {
                _gravedad = _fuerzaSalto;
            }
            else if (!Input.GetButtonDown("Jump"))
            {
                _gravedad = -10f;
            }
        }
    }

 
 
 
Qué puedo hacer para corregir esto?

ez. Tira raycast al suelo, si es menor que 0.5 puedes controlar el personaje sino no.


Cita de: leocub58 date=1474731915ez. Tira raycast al suelo, si es menor que 0.5 puedes controlar el personaje sino no.
   


No es mejor hacerlo ya dentro de un if .isGrounded

en lugar de tirar un raycast al suelo?

 

He probado con raycast y la verdad sigo teniendo el mismo problema xd

Simplemente pulso la tecla de salto, y mientras estoy en el aire puslo w/a/s/ o la d,

y se mueve hacia esa dirección muy horriblemente estando mitad del aire.


Parece el control del personaje del TES Oblivion, al saltar, lol.

 

Me imagino que en el update tendras puesto que si pulsas un boton lanze el metodo mover() y si pulsas otro boton lanza el metodo saltar() tu problema esta en que al pulsar "espacio" salta pero en ningun momento le estas diciendo que no se ejecute el metodo mover() ya que en el metodo saltar solo cambias la gravedad a parte que el else if de puedesaltar es un poco tonteria, una solucion es llamar al boolean de puedesaltar en el script que llame a mover(); if (puedesaltar)  mover();

Cita de: gokudera2 date=1474980896Me imagino que en el update tendras puesto que si pulsas un boton lanze el metodo mover() y si pulsas otro boton lanza el metodo saltar() tu problema esta en que al pulsar "espacio" salta pero en ningun momento le estas diciendo que no se ejecute el metodo mover() ya que en el metodo saltar solo cambias la gravedad a parte que el else if de puedesaltar es un poco tonteria, una solucion es llamar al boolean de puedesaltar en el script que llame a mover(); if (puedesaltar)  mover();
   


Tengo tanto el salto como el movimiento en el mismo script.

También intenté poner el código que hace que se mueva en el if (puedeSaltar),

pero ocurre que al darle al Play el player se queda quieto sin poder moverse.


Deja que vuelva a incluir el código, pero esta vez completo:
 

using UnityEngine;
using System.Collections;
[DisallowMultipleComponent]
[RequireComponent(typeof(CharacterController))]
public class ControladorJugador : MonoBehaviour
{
  /// Atributos.
  [SerializeField]
  private CharacterController _cc = null;
  [SerializeField]
  private bool _puedeSaltar = true;
  [SerializeField]
  private bool _puedeCorrer = true;
  [SerializeField]
  private bool _estaCorriendo = false;
  [Range(1f, 20f)]
  [SerializeField]
  private float _velocidadActual = 5f;
  [SerializeField]
  private float _gravedad = 0f;
  private float _gravedadOriginal = -10f;
  [SerializeField]
  private bool _estaColisionando = false;
  [SerializeField]
  private float _fuerzaSalto = 5.2f;
  [SerializeField]
  private float _contCorrer = 0f;
 
  /// Propiedades.
  public CharacterController CC
  {
    get { return _cc; }
  }
  public bool PuedeSaltar
  {
    get { return _puedeSaltar; }
    set { _puedeSaltar = value; }
  }
  public bool PuedeCorrer
  {
    get { return _puedeCorrer; }
    set { _puedeCorrer = value; }
  }
  public bool EstaCorriendo
  {
    get { return _estaCorriendo; }
    set { _estaCorriendo = value; }
  }
  public float VelocidadActual
  {
    get { return _velocidadActual; }
    set { _velocidadActual = value; }
  }
 
  /// Sistema.
  void Awake()
  {
    _cc = GetComponent<CharacterController>();
  }
  void Start()
  {
    _gravedad = _gravedadOriginal;
  }
  void Update()
  {
    MovimientoGeneral();
  }
  void OnTriggerEnter(Collider el)
  {
    if (el.gameObject.tag == "Obstaculo")
    {
      _estaColisionando = true;
    }
  }
  void OnTriggerExit(Collider el)
  {
    if (el.gameObject.tag == "Obstaculo")
    {
      _estaColisionando = false;
    }
  }
 
  /// Métodos.
  public void MovimientoGeneral()
  {
    // Movimiento.
    float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
    float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
    Vector3 _movimiento = new Vector3(_movHorizontal, _gravedad, _movVertical);
   
    _movimiento = transform.rotation * _movimiento;
    _cc.Move(_movimiento * Time.deltaTime);
   
    /// En el suelo.
    if (_cc.isGrounded)
    {
      _puedeSaltar = true;
      _puedeCorrer = true;
     
      /// Correr.
      if (_puedeCorrer)
      {
        if (Input.GetKey("w") && Input.GetKey("left shift") && !_estaColisionando)
        {
          float _maxContCorrer = 0.3f;
          _contCorrer += 1f * Time.deltaTime;
         
          if (_contCorrer >= _maxContCorrer)
          {
            _velocidadActual = 10f;
            _estaCorriendo = true;
            _contCorrer = _maxContCorrer;
          }
        }
        else
        {
          DejarDeCorrer();
        }
      }
      else
      {
        DejarDeCorrer();
      }
    }
    /// En el aire.
    else
    {
      // Aplica gravedad.
      _gravedad += Physics.gravity.y * Time.deltaTime;
     
      _puedeSaltar = false;
      _puedeCorrer = false;
    }
   
    /// Salto.
    if (_puedeSaltar)
    {
      if (Input.GetButtonDown("Jump"))
      {
        _gravedad = _fuerzaSalto;
      }
      else
      {
        _gravedad = _gravedadOriginal;
      }
    }
   
    /// Colisiones con obstáculos.
    if (_cc.isGrounded && _estaColisionando)
    {
      // Evita correr como un tonto contra una pared/obstáculo.
      _puedeCorrer = false;
    }
  }
  public void DejarDeCorrer()
  {
    _velocidadActual = 5f;
    _estaCorriendo = false;
    _contCorrer = 0f;
  }
}

 
 
 
Espero que me puedan ayudar.

Vale es lo que yo pensaba fijate que en el metodo update() estas constantemente lanzando el metodo movimientogeneral() y nada mas entrar al metodo tenemos estas lineas
 

   float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
    float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
    Vector3 _movimiento = new Vector3(_movHorizontal, _gravedad, _movVertical);
   
    _movimiento = transform.rotation * _movimiento;
    _cc.Move(_movimiento * Time.deltaTime);

 
esto no lo estas controlando en ningun momento por lo que esta constantemente cogiendo esos valores y por ende este en el estado que este puede moverse puedes hacer esto y deberia de funcionarte
 

 if (_puedeSaltar)
    {    
float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
    float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
    Vector3 _movimiento = new Vector3(_movHorizontal, _gravedad, _movVertical);
   
    _movimiento = transform.rotation * _movimiento;
    _cc.Move(_movimiento * Time.deltaTime);
  }

 
tambien un consejo para ahorrarte algunas lineas en un metodo que se ejecuta constantemente no hace falta que pongas else porque al salir del if continuara leyendo el codigo.

Cita de: gokudera2 date=1475006021Vale es lo que yo pensaba fijate que en el metodo update() estas constantemente lanzando el metodo movimientogeneral() y nada mas entrar al metodo tenemos estas lineas
   
   

   float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
    float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
    Vector3 _movimiento = new Vector3(_movHorizontal, _gravedad, _movVertical);
   
    _movimiento = transform.rotation * _movimiento;
    _cc.Move(_movimiento * Time.deltaTime);

   
      esto no lo estas controlando en ningun momento por lo que esta constantemente cogiendo esos valores y por ende este en el estado que este puede moverse puedes hacer esto y deberia de funcionarte
   
   

 if (_puedeSaltar)
    {    
float _movVertical = Input.GetAxis("Vertical") * _velocidadActual;
    float _movHorizontal = Input.GetAxis("Horizontal") * _velocidadActual;
    Vector3 _movimiento = new Vector3(_movHorizontal, _gravedad, _movVertical);
   
    _movimiento = transform.rotation * _movimiento;
    _cc.Move(_movimiento * Time.deltaTime);
  }

   
      tambien un consejo para ahorrarte algunas lineas en un metodo que se ejecuta constantemente no hace falta que pongas else porque al salir del if continuara leyendo el codigo.
   


Muchas gracias por volver a responder!
 
He intentado nuevamente hacer esto que me dices,

y funciona bien... hasta que salto y entonces el player se queda suspendido en el aire sin

poder moverse de nuevo, ya que al estar en el aire, _puedeSaltar es false (para evitar el doble salto),

entonces por esa razón no me sirve ese método :(
 
 
 
Y gracias por el consejo, lo tendré en cuenta!

Otra cosa que puedes hacer es permitir que el Player mueva al personaje durante el salto, pero no durante la caída, tras el salto.

Cita de: pioj date=1475179772Otra cosa que puedes hacer es permitir que el Player mueva al personaje durante el salto, pero no durante la caída, tras el salto.
   


También es buena esa para tener en cuenta.
 
Voy a probarlo 

Noviembre 15, 2016, 04:16:50 AM #11 Ultima modificación: Noviembre 15, 2016, 04:17:39 AM por lightbug
Una cosa que a mi me perturba, quiza a vos no, es lo de llamar a la fuerza del salto "gravedad", te vas a enliar bastante sobre todo si en el futuro queres meter muchos mas movimientos. Yo utilizo dos tipos de movimientos: el frontal y horizontal (ejemplo en el suelo) y el vertical (saltando y gravedad). Te dejo un ejemplo mio:
 

void Update () {
    moveVector = Vector3.zero;   //el movimiento basico para el frente y los costados
    //Input
    if (Input.GetKey (KeyCode.W)) {   
    moveVector += transform.forward;
    } else if (Input.GetKey (KeyCode.S)) {               
    moveVector -= transform.forward;
    }
    if (Input.GetKey (KeyCode.D)) {   
    moveVector += transform.right;
    } else if (Input.GetKey (KeyCode.A)) {               
    moveVector -= transform.right;
    }
 
    //Salto  ------> OJO, aca puedo saltar tambien en el aire
    if (Input.GetKeyDown (KeyCode.Space))
    vertical = Vector3.up * jumpFactor;         
 
    //Aca esta la magia
    if (!Player.controller.isGrounded) {
    moveVector *= walkSpeed / 5 ;
    } else {
    moveVector *= walkSpeed;
    }
    //Gravity
    vertical += Physics.gravity * Time.deltaTime;
}
void LateUpdate(){
Player.controller.Move ((moveVector + vertical) * Time.deltaTime);      //Solo un Move por frame
}

 
Lo de moverse en el aire se llama AirControl y esta bueno siempre tenerlo ahi aunque no se use, yo personalmente prefiero que se mueva como un campeon por el aire, me da mas la sensacion de "juego".
 
 
 
Salu2
 
 

Etiquetas: