Jump to content
Null

[AYUDA] Corregir control del player en el aire

Recommended Posts

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?

:7_sweat_smile:

Share this post


Link to post
Share on other sites
On 24/9/2016 at 17:45, leocub58 said:

ez. 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?
 

Share this post


Link to post
Share on other sites

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.
 

Share this post


Link to post
Share on other sites

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();

Share this post


Link to post
Share on other sites
hace 2 horas, gokudera2 said:

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();

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
On 27/9/2016 at 21:53, gokudera2 said:

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.

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!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites
hace 19 horas, pioj said:

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.

También es buena esa para tener en cuenta.

Voy a probarlo :3_grin:

Share this post


Link to post
Share on other sites

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

 

Edited by lightbug

Share this post


Link to post
Share on other sites

UnitySpain © Todos los derechos reservados 2020
×
×
  • Create New...