no matter what I do with my code, the Player doesn't seem to want to jump. Everything is referenced correctly in Unity and the code is hopefully error free. I've also checked to see if the Input System is corresponding to what I've got pressed. The only thing I can think of is the force isn't strong enough for the player to lift off of the ground, due to the high gravity (7f). But I lowered the gravity and nothing changed. Thanks for the help in advance.
using System.Collections;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
private float horizontal;
private float speed = 8f;
private float jumpingPower = 16f;
private bool isFacingRight = true;
private bool isJumping;
private float coyoteTime = 0.2f;
private float coyoteTimeCounter;
private float jumpBufferTime = 0.2f;
private float jumpBufferCounter;
[SerializeField] private Rigidbody2D rb;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
private void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
if (IsGrounded())
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump"))
{
jumpBufferCounter = jumpBufferTime;
}
else
{
jumpBufferCounter -= Time.deltaTime;
}
if (coyoteTimeCounter > 0f && jumpBufferCounter > 0f && !isJumping)
{
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
jumpBufferCounter = 0f;
StartCoroutine(JumpCooldown());
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0f)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * 0.5f);
coyoteTimeCounter = 0f;
}
Flip();
}
private void FixedUpdate()
{
rb.velocity = new Vector2(horizontal * speed, rb.velocity.y);
}
private bool IsGrounded()
{
return Physics2D.OverlapBox(groundCheck.position, groundCheck.GetComponent<BoxCollider2D>().size, 0f, groundLayer);
//return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
private void Flip()
{
if (isFacingRight && horizontal < 0f || !isFacingRight && horizontal > 0f)
{
Vector3 localScale = transform.localScale;
isFacingRight = !isFacingRight;
localScale.x *= -1f;
transform.localScale = localScale;
}
}
private IEnumerator JumpCooldown()
{
isJumping = true;
yield return new WaitForSeconds(0.4f);
isJumping = false;
}
}
The code works fine and the player jumps and moves without problems
Make sure to perform these steps inside Unity Engine
Inside the player you must add
Rigidbody2D
Box Collider2D
the code
Inside the code you must specify
Ground Layer : "Ignore Raycast"
Ground Check : "The ground the player is walking on"
And inside the ground must be added
Layer : "Ignore Raycast"
Component: "Box Collider2D"
As in these pictures
Player
enter image description here
Ground
enter image description here
The code worked. The ground check had a collider on it, when it wasn't necessary. The ground check in reality was inside the player.
Related
I'm trying to learn unity 2D and now iI need to do animations. I did walking animation, falling animation, jumping animation and the idle animation. However, when I jump, the falling animation doesn't play as intended. The falling animation isn't working properly, so it looks like this:
https://www.awesomescreenshot.com/video/8054610?key=208b095723f0bd4d8dfb936c88485e76
So when I'm falling, it doesn't play the animation right.
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private Animator anim;
private SpriteRenderer sprite;
private enum MovementState { idle, running, jumping, falling }
private float dirX = 0f;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 5f;
private void Start()
{
Debug.Log("program started...");
rb = GetComponent<Rigidbody2D>();
sprite = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
}
private void Update()
{
dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
if (Input.GetButtonDown("Jump"))
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
}
Animation();
}
private void Animation()
{
MovementState state;
if (dirX > 0f)
{
state = MovementState.running;
sprite.flipX = false;
}
else if (dirX < 0f)
{
state = MovementState.running;
sprite.flipX = true;
}
else
{
state = MovementState.idle;
}
if (rb.velocity.y > .1f)
{
state = MovementState.jumping;
}
else if (rb.velocity.y < -.1f)
{
state = MovementState.falling;
}
anim.SetInteger("state", (int)state);
}
}
i don't know how to fix it, i've searched for about a hour how to fix it.
animations setting (my settings)
the settings that i want
There's a couple of things you can try to do to narrow down the issue. See if commenting out this else statement has an effect on the issue you are experiencing between jump and fall.
else
{
state = MovementState.idle;
}
I think this else could possibly to interrupt your Y velocity animation transition when the object reaches the max height of the jump.
Try to comment out different part of your if else statements until you find the culprit.
Also try to get rid of the overlap on the transition between jump and fall. I think you want to instantly move from jump animation to fall animation.
I suggest you to use two different floats for your animations, one for Movement and one for Jumping.
Then something like following to handle them.
private void Animation() {
sprite.flipX = dirX > 0f;
//Do some sort of ground check
if (isGrounded) {
anim.SetFloat("Move", dirX);
}
else {
anim.SetFloat("Jump", rb.velocity.y);
}
}
And of course you need to change your condition that you have setup in your Animator as well from your Animator window to make it work.
As it has been suggested, I would add what is called a ground check to your player, which is exactly what it sounds like. An easy way to do this would be to Raycast downward from your player's position offset by the sprite's extents and only detect casts against a specific ground LayerMask.
Once you have a ground check done, you can set the state of your animation based on 4 criteria.
Is the player grounded?
What is your relative velocity? (Positive / Negative)
With your four states, the logic would look as follows
•Idle - Grounded and X Velocity equals 0 (Or default)
•Running - Grounded and X Velocity not equal to 0
•Jumping - Not Grounded and Y Velocity greater than or equal to 0
•Falling - Not Grounded and Y Velocity less than 0
With this in mind, here is how I would edit your existing code to work as intended
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2D rb;
private Animator anim;
private SpriteRenderer sprite;
private enum MovementState { idle, running, jumping, falling }
private float dirX = 0f;
[SerializeField] private float moveSpeed = 7f;
[SerializeField] private float jumpForce = 5f;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float groundLengthCheck = 0.03f;
private Vector3 spriteGroundOffset = Vector3.zero;
private bool isGrounded = false;
private void Start()
{
Debug.Log("program started...");
rb = GetComponent<Rigidbody2D>();
sprite = GetComponent<SpriteRenderer>();
anim = GetComponent<Animator>();
// offset the raycast check to be half our sprite bounds in the Y (the bottom of your sprite)
spriteGroundOffset = new Vector3(0f, sprite.bounds.extents.y, 0f);
}
private void Update()
{
dirX = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
// determine if our player is grounded by casting down from their feet with our slight offset
isGrounded = Physics2D.Raycast(transform.position - spriteGroundOffset, Vector2.down, groundLengthCheck, groundMask);
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
}
Animation();
}
private void Animation()
{
// default our state to idle - as if we are just standing
MovementState state = MovementState.idle;
// change
if (isGrounded)
{
if (dirX > 0f)
{
state = MovementState.running;
sprite.flipX = false;
}
else if (dirX < 0f)
{
state = MovementState.running;
sprite.flipX = true;
}
}
else
{
if (rb.velocity.y > 0)
{
state = MovementState.jumping;
}
else if (rb.velocity.y < 0f)
{
state = MovementState.falling;
}
}
anim.SetInteger("state", (int)state);
}
}
Keep in mind
Add a new layer, assign it to your ground objects, and set the serialized field groundMask to check for this new layer.
There are a few other issues that might come about with the current code. The current snippet I have provided only fixes the issue related to jumping/falling.
Here is a gif of the current code in action - I am using a public domain sprite as I do not currently have any art for a 2D player.
I am trying to flip my character sprite when moving left in my game, and I have followed multiple tutorials however my sprite does not seem to flip. It is always facing the same way.
Below is my code for my character's movement. I have created a Flip() function and 2 if statements used to call the function. The character can move left, right, up and down (no jumping).
I cannot seem to see where an error would be and why it is not flipping, so any help would be appreciated. thank you.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
// Start is called before the first frame update
private Animator animate;
public float moveSpeed = 6f;
bool facingRight = true;
public Rigidbody2D rb;
Vector2 movement;
private void Start()
{
animate = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animate.SetFloat("Speed", Mathf.Abs(movement.x));
if(movement.x < 0 && facingRight)
{
Flip();
}
else if (movement.x > 0 && !facingRight)
{
Flip();
}
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
void Flip()
{
Vector3 currentScale = gameObject.transform.localScale;
currentScale.x *= -1;
gameObject.transform.localScale = currentScale;
facingRight = !facingRight;
}
}
Updated code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
// Start is called before the first frame update
private Animator animate;
public float moveSpeed = 6f;
bool facingRight = true;
public Rigidbody2D rb;
Vector2 movement;
private void Start()
{
animate = gameObject.GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
animate.SetFloat("Speed", Mathf.Abs(movement.x));
if (movement.x < 0 && facingRight)
{
GetComponent<SpriteRenderer>().flipX = true;
}
else if (movement.x > 0 && !facingRight)
{
GetComponent<SpriteRenderer>().flipX = false;
}
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
void Flip()
{
Vector3 currentScale = gameObject.transform.localScale;
currentScale.x *= -1;
gameObject.transform.localScale = currentScale;
facingRight = !facingRight;
}
}
Try to set the flipX property of the SpriteRenderer.
GetComponent<SpriteRenderer>().flipX = true;
You have an animator attached to the game object, if the scale value is controlled by the animation clip, you cannot change it. A typical workaround is give the game object an empty parent and change its scale.
Player <---- Change scale here
Model <---- Animator here
transform.Rotate(0f, 180f, 0f); you have to change y while fliping
will work better instead of using currentScale.x *= -1;
gameObject.transform.localScale = currentScale;
This code worked for me
private void Flip()
{
// Rotate the player
if (transform.localEulerAngles.y != 180 && !facingRight)
transform.Rotate(0f, 180f, 0f);
else if(transform.localEulerAngles.y != 0 && facingRight)
transform.Rotate(0f, -180f, 0f);
// player flip point of attck also flip is direction
//transform.Rotate(0f, 180f, 0f);
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
GetComponent<SpriteRenderer>().flipX = true;
isLookingRight = false;
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
GetComponent<SpriteRenderer>().flipX = false;
isLookingRight = true;
}
Going to right
Going to left
I'm making a 2D platformer with Unity. I used this tutorial to write this code but changed it a little bit. I want to support both keyboard and gamepad, so I use the new Input System. I've defined three variables called GroundedRememeber, JumpPressedRemember and JumpPressedRememberTime and basically they work like timers and check if the player leaves the ground and then the player can jump when he is near the ground without need to touch it and I want to use it instead of famous "groundCheck". But the problem is that these timers are not working and the player can jump forever even in the air when I press jump button rapidly. Also, as you can see, I added a LayerMask named "groundLayers" for the player to jump only on this type of objects but when I choose "Ground" in the "groundLayers" slot in the Inspector, the player can't jump anymore.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerController : MonoBehaviour, PlayerInputActions.IPlayerActions
{
private PlayerInputActions controls;
[SerializeField] LayerMask groundLayers;
private Rigidbody2D rb;
private Animator anim;
private bool facingRight = true;
private Vector2 moveInput;
[SerializeField] private float jumpForce;
float JumpPressedRemember = 0;
[SerializeField] float JumpPressedRememberTime = 0.2f;
float GroundedRemember = 0;
[SerializeField] float GroundedRememberTime = 0.25f;
[SerializeField] float HorizontalAcceleration = 1;
[SerializeField] [Range(0, 1)] float HorizontalDampingBasic = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenStopping = 0.5f;
[SerializeField] [Range(0, 1)] float HorizontalDampingWhenTurning = 0.5f;
[SerializeField] [Range(0, 1)] float JumpHeight = 0.5f;
private void Awake()
{
controls = new PlayerInputActions();
controls.Player.SetCallbacks(this);
}
void Start()
{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void PlayerInputActions.IPlayerActions.OnMove(InputAction.CallbackContext context)
{
moveInput = context.ReadValue<Vector2>();
}
void Jump() {
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Force);
GroundedRemember = 0;
JumpPressedRemember = 0;
}
bool TryJump() {
if (GroundedRemember > 0) {
Jump();
return true;
} else {
JumpPressedRemember = JumpPressedRememberTime;
return false;
}
}
void PlayerInputActions.IPlayerActions.OnJump(InputAction.CallbackContext context)
{
jumpForce = context.ReadValue<float>();
switch (context.phase) {
case InputActionPhase.Performed:
TryJump();
break;
}
}
void FixedUpdate()
{
if(facingRight == false && moveInput.x > 0){
Flip();
}else if (facingRight == true && moveInput.x < 0){
Flip();
}
}
void Flip(){
facingRight = !facingRight;
Vector3 Scaler = transform.localScale;
Scaler.x *= -1;
transform.localScale = Scaler;
}
void OnEnable()
{
controls.Enable();
}
void OnDisable()
{
controls.Disable();
}
void Update()
{
Vector2 GroundedBoxCheckPosition = (Vector2)transform.position + new Vector2(0, -0.01f);
Vector2 GroundedBoxCheckScale = (Vector2)transform.localScale + new Vector2(-0.02f, 0);
bool Grounded = Physics2D.OverlapBox(GroundedBoxCheckPosition, transform.localScale, 0, groundLayers);
GroundedRemember -= Time.deltaTime;
if (Grounded)
{
GroundedRemember = GroundedRememberTime;
}
JumpPressedRemember -= Time.deltaTime;
if ((JumpPressedRemember > 0)) {
TryJump();
}
rb.velocity = new Vector2(rb.velocity.x, jumpForce);
float HorizontalVelocity = rb.velocity.x;
HorizontalVelocity += moveInput.x;
if (Mathf.Abs(moveInput.x) < 0.01f)
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenStopping, Time.deltaTime * 10f);
else if (Mathf.Sign(moveInput.x) != Mathf.Sign(HorizontalVelocity))
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingWhenTurning, Time.deltaTime * 10f);
else
HorizontalVelocity *= Mathf.Pow(1f - HorizontalDampingBasic, Time.deltaTime * 10f);
rb.velocity = new Vector2(HorizontalVelocity, rb.velocity.y);
}
}
If you know how much the player jumps for, then try maybe adding a delay to the next jump
Maybe using the Invoke() function ur just using Coroutines if you know how to use them.
But i would still recommend using a Ground Check since it's practical and just easier and i don't see a reason why you wouldn't use it.
The grounded state for my character controller flickers on and off constantly at what seems to be every frame. From what I know, it's supposed to check if the player is grounded through player.isGrounded, but something else is moving it back up.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerCharacterController: MonoBehaviour {
static Animator anim;
public bool walking;
public GameObject playerModel, Hero;
//Transforms
public Transform playerCam, character, centerPoint;
private Vector3 moveDirection;
//character controller declaration
CharacterController player;
//Mouse Rotation
private float rotX, rotY;
//Mouse Y Position
public float mouseYPosition = 1f;
//Mouse Sensitivity
public float Sensitivity = 10f;
//Mouse Zoom
private float zoom;
public float zoomSpeed = 2;
//Clamping Zoom
public float zoomMin = -2f;
public float zoomMax = -10f;
public float rotationSpeed = 5f;
//Move Front Back left & Right
private float moveFB, moveLR;
//Movement Speed
public float Speed = 2f;
//Velocity of Gravity
public float verticalVelocity;
//Jump Distance
public float jumpDist = 5f;
//Multiple Jumps
int jumpTimes;
//To use with Dialogue Manager
public DialogueManager DiagM;
public AudioClip jumpSound;
public AudioClip HurtSound;
public AudioClip PunchSound;
AudioSource audioSource;
//knockback
public float knockBackForce;
public float knockBackTime;
private float knockBackCounter;
// Use this for initialization
void Start ()
{
//character controller
player = GameObject.Find("Player").GetComponent<CharacterController> ();
StartCoroutine(MyCoroutine(character));
anim = GetComponent<Animator>();
//mouse zoom
zoom = -3;
centerPoint.transform.position = playerCam.transform.position;
centerPoint.transform.parent = null;
audioSource = GetComponent<AudioSource>();
}
IEnumerator MyCoroutine (Transform character)
{
if (player.isGrounded == true)
{
anim.SetBool("isFalling",false);
//anim.SetBool("isIdling", true);
yield return new WaitForSeconds(0);
}
}
// Update is called once per frame
void Update ()
{
//Mouse Zoom Input
zoom += Input.GetAxis ("Mouse ScrollWheel") * zoomSpeed;
if (zoom > zoomMin)
zoom = zoomMin;
if (zoom < zoomMax)
zoom = zoomMax;
//Mouse Camera Input
playerCam.transform.localPosition = new Vector3 (0, 0, zoom);
//Mouse Rotation
rotX += Input.GetAxis ("Mouse X") * Sensitivity;
rotY -= Input.GetAxis ("Mouse Y") * Sensitivity;
//Clamp Camera
rotY = Mathf.Clamp (rotY, -60f, 60f);
playerCam.LookAt (centerPoint);
centerPoint.localRotation = Quaternion.Euler (rotY, rotX, 0);
//Movement Speed
if (knockBackCounter <= 0)
{
moveDirection = (transform.forward * Input.GetAxis("Vertical")) + (transform.right * Input.GetAxis("Horizontal"));
moveDirection = moveDirection * Speed;
moveDirection.y = verticalVelocity;
player.Move(moveDirection * Time.deltaTime);
//Movement Rotation
centerPoint.position = new Vector3 (character.position.x, character.position.y + mouseYPosition, character.position.z);
//knockback disable
//Movement Input
if (Input.GetAxis("Vertical") != 0 || Input.GetAxis("Horizontal") != 0)
{
transform.rotation = Quaternion.Euler(0f, centerPoint.rotation.eulerAngles.y, 0f);
Quaternion turnAngle = Quaternion.LookRotation(new Vector3(moveDirection.x, 0f, moveDirection.z));
playerModel.transform.rotation = Quaternion.Slerp(playerModel.transform.rotation, turnAngle, Time.deltaTime * rotationSpeed);
if (player.isGrounded == true)
{
anim.SetBool("isWalking", true);
anim.Play("Running");
}
}
else
{
StartCoroutine(MyCoroutine(character));
}
if (Input.GetButtonDown("LHand"))
{
audioSource.PlayOneShot(PunchSound, 1F);
anim.Play("RPunch");
}
if (player.isGrounded == true)
{
jumpTimes = 0;
//verticalVelocity = -Physics.gravity.y * Time.deltaTime;
verticalVelocity = 0;
}
else
{
verticalVelocity += Physics.gravity.y * Time.deltaTime;
anim.SetBool("isWalking", false);
anim.SetBool("isFalling", true);
}
if (jumpTimes < 1)
{
if (Input.GetButtonDown("Jump"))
{
verticalVelocity += jumpDist;
anim.Play("Jump");
audioSource.PlayOneShot(jumpSound, 1F);
jumpTimes += 1;
}
}
}
else
{
knockBackCounter -= Time.deltaTime;
}
}
public void Knockback(Vector3 direction)
{
knockBackCounter = knockBackTime;
anim.Play("Jump");
audioSource.PlayOneShot(HurtSound, 50F);
moveDirection = direction * knockBackForce;
moveDirection.y = knockBackForce;
}
}
It looks like it has to do with the verticalVelocity lines, but so far I have only tried setting verticalVelocity = 0 and that works until I have actually moved the character. What could I change to stop the flickering?
Probably it is already solved, but the reason for that is that if you are using Character Controller you should apply gravity ALL the time to the character.
When the character collides with a object, it actually enters a little bit inside this object, then Unity pushes the character back away from the object, until it is no longer touching it. At this point, your gravity starts acting again, and re initiziling the cycle.
You need to apply gravity 100% of the time to create enough force to "balance" this fight with the floor. Could be a smaller "gravity" like 1. No need to be your gravity variable.
Also, on top of that, I like to add a "Coyote time", and make my on IsGrounded() method, as follows:
public bool IsGrounded()
{
return CoyoteTime < CoyoteTimeMax;
}
public void CoyoteControl()
{
if (CharController.isGrounded)
{
CoyoteTime = 0;
}
else
{
CoyoteTime += Time.deltaTime;
}
}
And then I call the CoyoteControl() on Update(), and I can call IsGrounded() whenever I need.
On the inspector I usually set the CoyoteTimeMax to 0.1 and it makes falls more smooth.
As per you comment. You should not determine if your player is grounded by checking an animation parameter. The best way is to use a RayCast(). So what you have to do:
Create a Layer named Ground, and add all the platforms in your
scene to that layer.
Create a bool variable
i.e
bool isGrounded;
Create a function to check if the character is grounded
Something like:
bool checkGrounded(){
return Physics.Raycast(transform.position, Vector3.down, 2f, 1 << LayerMask.NameToLayer("Ground")));
}
In this answer you can read about the involved parameters in the Raycast
Finally inside the update check if the player is grounded or not
Something like:
void Update(){
isGrounded = checkGrounded();
}
I have found that the isGrounded check can change over the course of the Update() function if you are checking it multiple times. Assigning it to a variable at the beginning of the function may solve the flickering issue.
void Update()
{
bool isGrounded = characterController.isGrounded;
...
I'm learning Unity, and I'm writing a player script. Based on the script I've written, I expect to see my player to be able to jump while standing still, while moving left, and while moving right. The player cant jump if it is moving right at the same time. I did a bunch of refactoring and reorganizing. I think it might have something to do with Input.GetButton("Jump").
Also, I changed rb2d.AddForce(new Vector2(0.0f, jumpHeight)) to rb2d.velocity = new Vector2(0.0f, jumpHeight), but the player just disappears.
Here's my script so far:
private Rigidbody2D rb2d;
[SerializeField]
private LayerMask whatIsGround;
private bool isTouchingGround;
private bool facingRight = true;
[SerializeField]
private float speed;
[SerializeField]
private float jumpHeight;
[SerializeField]
private Transform[] groundPoints;
[SerializeField]
private float groundRadius;
// Use this for initialization
void Start () {
rb2d = GetComponent<Rigidbody2D>();
}
private void FixedUpdate() {
float moveHorizontal = Input.GetAxis("Horizontal");
Flip(moveHorizontal);
if (Input.GetButton("Jump") && IsGrounded()) {
rb2d.AddForce(new Vector2(0.0f, jumpHeight));
}
rb2d.velocity = new Vector2(moveHorizontal * speed, rb2d.velocity.y);
}
private void Flip(float horizontal) {
if ((horizontal > 0 && !facingRight) || (horizontal < 0 && facingRight)) {
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
private bool IsGrounded() {
if (rb2d.velocity.y <= 0) {
foreach (Transform point in groundPoints) {
Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);
foreach (Collider2D collider in colliders) {
if (collider.gameObject != gameObject)
return true;
}
}
}
return false;
}
I found a solution, but I'm not sure why it fixed the problem. If you have an idea why, please comment below!
In the private bool IsGrounded() method, I removed the if statement checking if rb2d.velocity.y <= 0. I thought that would be a helpful check to see if the player is moving down or stationary. For some reason, moving the player right was making this if statement fail. This seems like a bug.