- Home /
Question by
Martinx903 · Apr 20, 2021 at 03:12 PM ·
bug2d-platformerproblem during runtime
I have a 2D platformer runnign with a character, but randomly the Input for the Jump (space) doesn't workds.
It's not because of the collider I think, but because of the Animations, I think the jump isn't getting the input because or of the animations, that until one finish it can't go to the other, or because of the detection of the input, that it gives priority to the movement than the jump.
{
//Private Variables
private Rigidbody2D rb2D;
private Animator anim;
private Collider2D coll2D;
private bool facingLeft = true;
//Inspector Variables
[SerializeField] private LayerMask ground;
[Range(0, 1)] [SerializeField] private float movementSmoothing = 0.5f;
[SerializeField] private float jumpForce = 40f;
[SerializeField] private float runSpeed = 4f;
[SerializeField] private float rollForce = 40f;
[SerializeField] private float startRollTimer;
//Physics Variables
private float horizontalMovement = 0f;
private bool isJumping = false;
private bool isRolling = false;
private float rollDirection;
private float currentRollTimer;
private Vector3 velocity = Vector3.zero;
//FSM
private enum State { idle,running,jumping,falling, rolling};
private State state = State.idle;
// Start is called before the first frame update
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
coll2D = GetComponent<Collider2D>();
anim = GetComponent<Animator>();
}
// This functin is called once per frame
void FixedUpdate()
{
if(Input.GetButtonDown("Jump") && coll2D.IsTouchingLayers(ground))
{
isJumping = true;
}
else
{
isJumping = false;
}
if (Input.GetButtonDown("Fire1") && coll2D.IsTouchingLayers(ground))
{
isRolling = true;
currentRollTimer = startRollTimer;
rb2D.velocity = Vector2.zero;
rollDirection = (int)horizontalMovement;
state = State.rolling;
}
//Detectamos la velocidad del jugador en base a si calca A o D y le pasamos al código un número entre -1 y 1.
horizontalMovement = Input.GetAxisRaw("Horizontal") * runSpeed;
Movement();
AnimationController();
anim.SetInteger("state", (int)state);
}
void Movement()
{
if (isJumping)
{
//Actualizamos su estado a saltando
state = State.jumping;
//Aplicamos una fuerza vertical que le lance al aire
rb2D.AddForce(new Vector2(0f, jumpForce));
}
if (isRolling)
{
rb2D.velocity = transform.right * rollDirection * rollForce;
currentRollTimer -= Time.fixedDeltaTime;
if(currentRollTimer <= 0)
{
isRolling = false;
}
}
//Cogemos la velocidad del personaje en base al input que te da Unity por los axis.
Vector3 targetVelocity = new Vector2(horizontalMovement * Time.fixedDeltaTime * 10f, rb2D.velocity.y);
//La smootheamos con esta función
rb2D.velocity = Vector3.SmoothDamp(rb2D.velocity, targetVelocity, ref velocity, movementSmoothing);
if (horizontalMovement > 0 && !facingLeft)
{
Flip();
}
else if (horizontalMovement <0 && facingLeft)
{
Flip();
}
}
void Flip()
{
//Cambiamos la forma en la que le pasamos al programa la dirección del personaje
facingLeft = !facingLeft;
//Multiplicamos la escala del personaje por 1 o -1 en base a si está mirando hacia la izq o no
Vector3 scale = transform.localScale;
scale.x *= -1;
transform.localScale = scale;
}
void AnimationController()
{
if(state == State.jumping)
{
if(rb2D.velocity.y < -.1f)
{
state = State.falling;
}
}
else if(state == State.falling)
{
if(coll2D.IsTouchingLayers(ground))
{
state = State.idle;
}
}
else if(state == State.rolling)
{
if(currentRollTimer <= 0 && coll2D.IsTouchingLayers(ground))
{
state = State.idle;
}
}
else if ((Mathf.Abs(horizontalMovement) > 0.2f) && coll2D.IsTouchingLayers(ground))
{
state = State.running;
}
else
{
state = State.idle;
}
}
}
Comment