Vexer
May 9, 2018, 1:42pm
1
Hey guys im trying to create a simple platformer with some nice animations the problem that i can’t seem to find a fix for is when i run and then jump i want to let the player jump in that direction but i don’t want the player to be able to run in the air. the problem that i have right now is that when i say if !isgrounded then isRunning = false but then my player also stops moving the second problem that i have is that i can’t run and jump for some reason my character gets blocked please help me guys!
[LIST=1]
[*]using System.Collections;
[*]using System.Collections.Generic;
[*]using UnityEngine;
[*]
[*]public class Player : MonoBehaviour {
[*]
[*] public float speed = 10, jumpVelocity = 10;
[*] private Rigidbody2D rb;
[*] private Animator anim;
[*]
[*] public bool isGrounded;
[*] public bool isRunning;
[*]
[*] private bool facingRight;
[*]
[*] [SerializeField]
[*] private bool airControl;
[*]
[*]
[*] // Use this for initialization
[*] void Start ()
[*] {
[*] facingRight = true;
[*] rb = gameObject.GetComponent<Rigidbody2D>();
[*] anim = gameObject.GetComponent<Animator>();
[*] }
[*]
[*] void OnCollisionEnter2D(Collision2D col)
[*] {
[*] if(col.gameObject.tag == "ground")
[*] {
[*] isGrounded = true;
[*] }
[*]
[*] }
[*]
[*] void OnCollisionExit2D(Collision2D col)
[*] {
[*] if (col.gameObject.tag == "ground")
[*] {
[*] isGrounded = false;
[*] }
[*]
[*] }
[*]
[*] // Update is called once per frame
[*] void FixedUpdate()
[*] {
[*] float horizontal = Input.GetAxis("Horizontal");
[*] HandleMovement(horizontal);
[*] Flip(horizontal);
[*] }
[*]
[*] void Update()
[*] {
[*] anim.SetBool("isGrounded", isGrounded);
[*] anim.SetBool("isRunning", isRunning);
[*] }
[*]
[*] private void HandleMovement(float horizontal)
[*] {
[*]
[*] if (Input.GetKey(KeyCode.D))
[*] {
[*] rb.velocity = Vector2.right * speed;
[*] isRunning = true;
[*] anim.SetBool("isRunning", true);
[*] }
[*]
[*] if (!Input.GetKey(KeyCode.D))
[*] {
[*] isRunning = false;
[*] anim.SetBool("isRunning", false);
[*] }
[*]
[*] if (Input.GetKey(KeyCode.A))
[*] {
[*] rb.velocity = Vector2.left * speed;
[*] isRunning = true;
[*] anim.SetBool("isRunning", true);
[*] }
[*]
[*] if (Input.GetButtonDown ("Jump") && isGrounded)
[*] {
[*] rb.velocity = Vector2.up * jumpVelocity;
[*] }
[*] }
[*]
[*] private void Flip(float horizontal)
[*] {
[*] if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
[*] {
[*] facingRight = !facingRight;
[*]
[*] Vector3 theScale = transform.localScale;
[*]
[*] theScale.x *= -1;
[*]
[*] transform.localScale = theScale;
[*] }
[*] }
[*]}
[*]
[/LIST]
Example of my problem: Screen capture - 053c0158e3b0cae8e993c16d89690380 - Gyazo
You’re overriding the velocity of your character every frame, so gravity can’t accumulate, that’s why you’re seeing such a slow descent. You need to set only the X velocity of the rigidbody with your horizontal movement.
Vexer
May 9, 2018, 5:42pm
3
GroZZleR:
You’re overriding the velocity of your character every frame, so gravity can’t accumulate, that’s why you’re seeing such a slow descent. You need to set only the X velocity of the rigidbody with your horizontal movement.
Could you give me an example line of code? I kinda understand what you mean but i don’t quite get it…
rb.velocity = new Vector2(Vector2.right * speed, rb.velocity.y); // keep the current Y velocity so gravity can accumulate
Vexer
May 9, 2018, 6:05pm
5
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour {
public float speed = 5;
public float jumpVelocity = 10;
private Rigidbody2D rb;
private Animator anim;
public bool isGrounded;
public bool isRunning;
private bool facingRight;
[SerializeField]
private bool airControl;
// Use this for initialization
void Start ()
{
facingRight = true;
rb = gameObject.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
}
void OnCollisionEnter2D(Collision2D col)
{
if(col.gameObject.tag == "ground")
{
isGrounded = true;
}
}
void OnCollisionExit2D(Collision2D col)
{
if (col.gameObject.tag == "ground")
{
isGrounded = false;
}
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
HandleMovement(horizontal);
Flip(horizontal);
}
void Update()
{
anim.SetBool("isGrounded", isGrounded);
anim.SetBool("isRunning", isRunning);
}
private void HandleMovement(float horizontal)
{
if (Input.GetKey(KeyCode.D))
{
rb.velocity = new Vector2(Vector2.right * speed, rb.velocity.x); // keep the current Y velocity so gravity can accumulate
isRunning = true;
anim.SetBool("isRunning", true);
}
if (!Input.GetKey(KeyCode.D))
{
isRunning = false;
anim.SetBool("isRunning", false);
}
if (Input.GetKey(KeyCode.A))
{
rb.velocity = new Vector2(Vector2.left * speed, rb.velocity.x); // keep the current Y velocity so gravity can accumulate
isRunning = true;
anim.SetBool("isRunning", true);
}
if (Input.GetKey(KeyCode.Space)&& isGrounded)
{
rb.velocity = new Vector2(Vector2.up * jumpVelocity, rb.velocity.y); // keep the current Y velocity so gravity can accumulate
anim.SetBool("isRunning", false);
}
}
private void Flip(float horizontal)
{
if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}
Hmm… it seems to give an error now…? : https://gyazo.com/808e6e558b5855f220207757cf227c99
Oops sorry, you don’t need the Vector2.right or Vector2.left any more since you’re setting the values indepedently, just speed and -speed. You also don’t want to mess with your jump code since there you do want to set the y velocity.
Some of latest post’s bits of code have “rb.velocity.x” as the second parameter, by the way. As in, not ‘.y’, which is what you want.
Vexer
May 9, 2018, 7:31pm
8
methos5k:
Some of latest post’s bits of code have “rb.velocity.x” as the second parameter, by the way. As in, not ‘.y’, which is what you want.
Thx for letting me know i also figured that was wrong so i changed that but i appreciate the help Do you have any idea why my character would be sliding? for some reason when i stop walking it still moves for like 0.1 second
could be because you never set the movement to zero.
I wrote this up in a few minutes, just as an example:
public class Test11 : MonoBehaviour
{
[SerializeField]
Rigidbody2D rb;
bool jump = false;
float speed = 2;
float jumpHeight = 3;
float playerBottom;
bool grounded = false;
void Start()
{
rb = GetComponent<Rigidbody2D>();
playerBottom = GetComponent<Collider2D>().bounds.extents.y;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && grounded) jump = true;
}
void FixedUpdate()
{
grounded = false;
RaycastHit2D hit = Physics2D.Raycast(transform.position - new Vector3(0, playerBottom, 0), Vector3.down, .05f);
float h = Input.GetAxisRaw("Horizontal");
if (hit)
{
grounded = true;
rb.velocity = new Vector2(h * speed, rb.velocity.y);
if (jump)
{
rb.velocity = new Vector2(rb.velocity.x, jumpHeight);
jump = false;
}
}
}
}
In case that helps.
Vexer
May 10, 2018, 9:44am
10
methos5k:
could be because you never set the movement to zero.
I wrote this up in a few minutes, just as an example:
public class Test11 : MonoBehaviour
{
[SerializeField]
Rigidbody2D rb;
bool jump = false;
float speed = 2;
float jumpHeight = 3;
float playerBottom;
bool grounded = false;
void Start()
{
rb = GetComponent<Rigidbody2D>();
playerBottom = GetComponent<Collider2D>().bounds.extents.y;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && grounded) jump = true;
}
void FixedUpdate()
{
grounded = false;
RaycastHit2D hit = Physics2D.Raycast(transform.position - new Vector3(0, playerBottom, 0), Vector3.down, .05f);
float h = Input.GetAxisRaw("Horizontal");
if (hit)
{
grounded = true;
rb.velocity = new Vector2(h * speed, rb.velocity.y);
if (jump)
{
rb.velocity = new Vector2(rb.velocity.x, jumpHeight);
jump = false;
}
}
}
}
In case that helps.
I created this line of code:
rb.velocity = Vector2.zero;
Where would i place this in my code?
Well, the general idea is that when you’re grounded and the horizontal input is none, you want the x portion of the velocity to be zero. This line of code from my example would do that:
rb.velocity = new Vector2(h * speed, rb.velocity.y);
The code is slightly easier with Input.GetAxis, which you already have in yours, too, but you just don’t use it (instead, using the GetKey).