I have a code for character movement but the grounded function never returns null and although i check for a layer of the ground it still thinks check the collision with the player's box collider so i can keep jumping forever
public float jumpVelocity;
private bool keyPressedW;
private bool isGrounded;
private Rigidbody2D rigidbody2d;
private BoxCollider2D boxCollider2d;
void Start()
{
rigidbody2d = transform.GetComponent<Rigidbody2D>();
boxCollider2d = transform.GetComponent<BoxCollider2D>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
keyPressedW = true;
if (IsGrounded())
isGrounded = true;
else isGrounded = false;
}
private void FixedUpdate()
{
if (keyPressedW && isGrounded)
{
rigidbody2d.velocity = Vector2.up * jumpVelocity;
keyPressedW = false;
}
}
private bool IsGrounded()
{
RaycastHit2D raycastHit2d = Physics2D.BoxCast(boxCollider2d.bounds.center,
boxCollider2d.bounds.size, 0f, Vector2.down * 0.1f ,
LayerMask.GetMask("Platform"));
Debug.Log(raycastHit2d.collider);
return raycastHit2d.collider != null;
}
You should use raycast and not box colliders. The code should look like this:
void Update()
{
if (Input.GetKeyDown(KeyCode.W))
keyPressedW = true;
}//remove the part that was here.
private void FixedUpdate()
{
if (keyPressedW && isGrounded)
{
rigidbody2d.velocity = Vector2.up * jumpVelocity;
keyPressedW = false;
}
}
private bool IsGrounded()
{
if (Physics2D.Raycast(transform.position, -transform.up, groundDistance, groundMask)
{
return true
}
return false
}
Related
i am using a 2 scripts, a player movement and a camera follow script. while jumping normally the jump is smooth, it is also smooth while moving my character. what i understand is that the camera follow script is somehow not allowing the jump to be smooth.here is the player movement script.
public class player_movement : MonoBehaviour
{
Rigidbody2D rb;
public float speed;
private float moveInput;
private bool isGrounded;
public Transform feetPos;
public float checkRadius;
public LayerMask whatIsGround;
public float jumpForce;
private float jumpTimeCounter;
public float jumpTime;
private bool isJumping;
private Animator anim;
void Start()
{
anim = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
}
void FixedUpdate()
{
movement();
}
private void movement()
{
moveInput = Input.GetAxisRaw("Horizontal");
rb.velocity = new Vector2(moveInput * speed, rb.velocity.y);
if (isGrounded == false && moveInput == 0)
{
anim.SetBool("is running", false);
}
else if (isGrounded == true && moveInput != 0)
{
anim.SetBool("is running", true);
}
else if(isGrounded == true && moveInput == 0)
{
anim.SetBool("is running", false);
}
else if (isGrounded == false && moveInput != 0)
{
anim.SetBool("is running", false);
}
}
void Update()
{
isGrounded = Physics2D.OverlapCircle(feetPos.position, checkRadius, whatIsGround);
if (moveInput > 0)
{
transform.eulerAngles = new Vector2(0, 0);
}
else if (moveInput < 0)
{
transform.eulerAngles = new Vector2(0, 180);
}
Jump();
}
private void Jump()
{
if (isGrounded == true && Input.GetKeyDown(KeyCode.Space))
{
isJumping = true;
jumpTimeCounter = jumpTime;
rb.velocity = Vector2.up * jumpForce;
}
if (Input.GetKey(KeyCode.Space))
{
if (jumpTimeCounter > 0 && isJumping == true)
{
rb.velocity = Vector2.up * jumpForce;
jumpTimeCounter -= Time.deltaTime;
}
else
{
isJumping = false;
}
}
if (Input.GetKeyUp(KeyCode.Space))
{
isJumping = false;
}
}
private void LateUpdate()
{
//Jump();
}
}
and here is the camera follow script.
public class cammeraFollow : MonoBehaviour
{
public GameObject followObject;
public Vector2 followOffset;
public float speed = 3f;
private Vector2 threshold;
private Rigidbody2D rb;
void Start()
{
threshold = calculateThreshold();
rb = followObject.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate()
{
Vector2 follow = followObject.transform.position;
float xDifference = Vector2.Distance(Vector2.right * transform.position.x, Vector2.right * follow.x);
float yDifference = Vector2.Distance(Vector2.up * transform.position.y, Vector2.up * follow.y);
Vector3 newPosition = transform.position;
if(Mathf.Abs(xDifference) >= threshold.x)
{
newPosition.x = follow.x;
}
if (Mathf.Abs(yDifference) >= threshold.y)
{
newPosition.y = follow.y;
}
float moveSpeed = rb.velocity.magnitude > speed ? rb.velocity.magnitude : speed;
transform.position = Vector3.MoveTowards(transform.position, newPosition, moveSpeed * Time.deltaTime);
}
private Vector3 calculateThreshold()
{
Rect aspect = Camera.main.pixelRect;
Vector2 t = new Vector2(Camera.main.orthographicSize * aspect.width / aspect.height, Camera.main.orthographicSize);
t.x -= followOffset.x;
t.y -= followOffset.y;
return t;
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Vector2 border = calculateThreshold();
Gizmos.DrawWireCube(transform.position, new Vector3(border.x * 2, border.y * 2, 1));
}
}
can anyone help me with this one.
FixedUpdate is not called every frame but in fixed intervals instead. It's more for physics and gameplay code.
Try changing the camera follow script to Update.
I have both player and ground with colliders 2D and player is supposed to stop on top of ground but instead it stops at the bottom of the ground.
Code
PlayerController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
private float moveSpeedStore;
public float speedMultiplier;
public float speedIncreateMilestone;
private float speedIncreateMilestoneStore;
private float speedMilestoneCount;
private float speedMilestoneCountStore;
public float jumpForce;
public float jumpTime;
private float jumpTimeCounter;
private bool stoppedJumping;
private bool canDoubleJump;
private Rigidbody2D myRigidbody;
public bool grounded;
public LayerMask whatIsGround;
public Transform groundCheck;
public float groundCheckRadius;
// private Collider2D myCollider;
private Animator myAnimator;
public GameManager theGameManager;
public AudioSource jumpSound;
public AudioSource deathSound;
// Start is called before the first frame update
void Start()
{
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
jumpTimeCounter = jumpTime;
speedMilestoneCount = speedIncreateMilestone;
moveSpeedStore = moveSpeed;
speedMilestoneCountStore = speedMilestoneCount;
speedIncreateMilestoneStore = speedIncreateMilestone;
stoppedJumping = true;
}
// Update is called once per frame
void Update()
{
grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, whatIsGround);
if(transform.position.x > speedMilestoneCount)
{
speedMilestoneCount += speedIncreateMilestone;
speedIncreateMilestone = speedIncreateMilestone * speedMultiplier;
moveSpeed = moveSpeed * speedMultiplier;
}
myRigidbody.velocity = new Vector2(moveSpeed, myRigidbody.velocity.y);
if(Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0) )
{
if(grounded)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
stoppedJumping = false;
jumpSound.Play();
}
if(!grounded && canDoubleJump)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
jumpTimeCounter = jumpTime;
stoppedJumping = false;
canDoubleJump = false;
jumpSound.Play();
}
}
if((Input.GetKey(KeyCode.Space) || Input.GetMouseButton(0)) && !stoppedJumping)
{
if(jumpTimeCounter > 0)
{
myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, jumpForce);
jumpTimeCounter -= Time.deltaTime;
}
}
if(Input.GetKeyUp(KeyCode.Space) || Input.GetMouseButtonUp(0))
{
jumpTimeCounter = 0;
stoppedJumping = true;
}
if(grounded)
{
jumpTimeCounter = jumpTime;
canDoubleJump = true;
}
myAnimator.SetFloat("Speed", myRigidbody.velocity.x);
myAnimator.SetBool("Grounded", grounded);
}
void OnCollisionEnter2D(Collision2D other) {
if(other.gameObject.tag == "killbox")
{
theGameManager.RestartGame();
moveSpeed = moveSpeedStore;
speedMilestoneCount = speedMilestoneCountStore;
speedIncreateMilestone = speedIncreateMilestoneStore;
deathSound.Play();
}
}
}
Player settings
Question
What should I do to hold my player on top of ground?
NOTE: it's my first question on unity ever so if you need any sort of code or data please just ask, I try my best to provide you what you need.
Thanks.
It looks like your collider is simply too high. You'll notice that the green box indicating your collider size and position is colliding with the correct spot on the ground. The bottom of it is just touching the top of the ground. You simply need to move the collider down on the player so that the bottom of the green box is at the bottom of the player's sprite.
I am making my first Game and now I have a problem: I have a jump button when i press it I am jumping but when I am in the air I can press it again and jump in the air again. How can fix that, so I can jump only on the ground. Here is my Code:
using UnityEngine;
using System.Collections;
using UnityStandardAssets.CrossPlatformInput;
public class Move2D : MonoBehaviour
{
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
}
public void Jump()
{
rigidBody.AddForce(transform.up * jumpSpeed, ForceMode2D.Impulse);
}
// Update is called once per frame
}
Here is the Code
public class Move2D : MonoBehaviour
{
public bool isGrounded = false;
public float speed = 5f;
public float jumpSpeed = 8f;
private float movement = 0f;
private Rigidbody2D rigidBody;
// Use this for initialization
void Start()
{
rigidBody = GetComponent<Rigidbody2D>();
}
private void OnCollisionEnter2D(Collision2D other)
{
if (other.gameObject.tag == "Ground") //you need to add a tag to your Ground, like "Ground"
{
isGrounded = true;
}
}
public void Jump()
{
rigidBody.AddForce(transform.up * jumpSpeed, ForceMode2D.Impulse);
isGrounded = false;
}
void Update()
{
if (Input.GetButtonDown("Jump") && isGrounded == true)
{
isGrounded = false;
Jump();
}
}
}
first of all you need a boolean (isGrounded). Then you have to check the collision between the player and the ground with
private void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.tag == "Ground") //you need to add a tag to your Ground, like "Ground"
{
isGrounded = true;
}
}
And then in the Update method add this code:
if (Input.GetKeyDown(KeyCode.Space) && isGrounded == true)
{
isGrounded = false;
Jump();
}
So as I said, I'm trying to make my character jump in Unity, but nothing is happening when I hit space, and Unity isn't throwing any errors.
public class Player : MonoBehaviour
{
private Rigidbody2D myRigidbody;
[SerializeField]
public float jumpSpeed;
private Animator myAnimator;
[SerializeField]
private float movementSpeed;
private bool facingLeft;
[SerializeField]
private Transform[] groundPoints;
[SerializeField]
private float groundRadius;
[SerializeField]
private LayerMask whatIsGround;
private bool isGrounded;
private bool jump;
[SerializeField]
private float jumpForce;
// Start is called before the first frame update
void Start()
{
facingLeft = true;
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
Debug.Log(horizontal);
isGrounded = IsGrounded();
HandleMovement(horizontal);
flip(horizontal);
}
private void HandleMovement(float horizontal)
{
myRigidbody.velocity = new Vector2(horizontal * movementSpeed, myRigidbody.velocity.y);
myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
if (isGrounded && jump)
{
isGrounded = false;
myRigidbody. AddForce(new Vector2(0, jumpForce));
}
}
private void HandleInput()
{
if (Input.GetKeyDown(KeyCode.Space))
{
jump = true;
}
}
private void flip(float horizontal)
{
if (horizontal < 0 && !facingLeft || horizontal > 0 && facingLeft)
{
facingLeft = !facingLeft;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
private bool IsGrounded()
{
if (myRigidbody.velocity.y <= 0)
{
foreach (Transform point in groundPoints)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
return true;
}
}
}
}
return false;
}
}
I've been following this tutorial for it, and his is jumping, but mine isn't. I think it might have something to do with the way I have the groundpoints set up, but I'm not sure if it's a error in the code or if it's in Unity.
You are not calling HandleInput anywhere.
add to fixed update
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
Debug.Log(horizontal);
isGrounded = IsGrounded();
HandleMovement(horizontal);
flip(horizontal);
HandleInput(); // add this so you are sampling input
}
I'm trying to make my game. I have a character and I'm trying to get it to jump. I can make the character walk, idle and slide but it won't jump. I'm doing all the coding in 1 script. I'm getting the attached error messages but not sure how to fix them. I've tried a number of things but can't get any of it to work.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.UIElements;
public class Player : MonoBehaviour
{
private Rigidbody2D myRigidbody;
private Animator myAnimator;
[SerializeField]
private float movementSpeed;
private bool walk;
private bool slide;
private bool facingRight;
[SerializeField]
private Transform[] groundPoints;
[SerializeField]
private float groundRadius;
private LayerMask whatIsGround;
private bool IsGrounded;
private bool jump;
[SerializeField]
private bool airControl;
[SerializeField]
private float jumpForce;
// Start is called before the first frame update
void Start()
{
facingRight = true;
myRigidbody = GetComponent<Rigidbody2D>();
myAnimator = GetComponent<Animator>();
}
void Update()
{
HandleInput();
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
isGround = IsGrounded();
HandleMovement(horizontal);
Flip(horizontal);
HandleWalk();
ResetValues();
}
private void HandleMovement(float horizontal)
{
if (!this.myAnimator.GetCurrentAnimatorStateInfo(0).IsTag("Walk")&& (isGround || airControl))
{
myRigidbody.velocity = new Vector2(horizontal * movementSpeed, myRigidbody.velocity.y);
}
if (isGround && jump)
{
isGround = false;
myRigidbody.AddForce(new Vector2(0, jumpForce));
}
if (slide && !this.myAnimator.GetCurrentAnimatorStateInfo(0).IsName("Slide"))
{
myAnimator.SetBool("slide", true);
}
else if (!this.myAnimator.GetCurrentAnimatorStateInfo(0).IsName("slide"))
{
myAnimator.SetBool("slide", false);
}
myAnimator.SetFloat("speed", Mathf.Abs(horizontal));
}
private void HandleWalk()
{
if (walk)
{
myAnimator.SetTrigger("walk");
myRigidbody.velocity = Vector2.zero;
}
}
private void HandleInput()
{
if (Input.GetKeyDown(KeyCode.Space))
{
jump = true;
}
if (Input.GetKeyDown(KeyCode.LeftShift))
{
walk = true;
}
if (Input.GetKeyDown(KeyCode.LeftControl))
{
slide = true;
}
}
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 void ResetValues()
{
walk = false;
slide = false;
}
private bool isGround()
{
if (myRigidbody.velocity.y <= 0)
{
foreach (Transform point in instance.groundPoints)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll (point.position, instance.groundRadius, instance.whatIsGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
return true;
}
}
}
}
return false;
}
}
Error messages for player to jump
Rename field private bool IsGrounded; to private bool isGround;
Also you need to change the method name private bool isGround() {} to private bool IsGrounded() {}
And remove instance from IsGrounded method.
private bool IsGrounded()
{
if (myRigidbody.velocity.y <= 0)
{
foreach (Transform point in groundPoints)
{
Collider2D[] colliders = Physics2D.OverlapCircleAll(point.position, groundRadius, whatisGround);
for (int i = 0; i < colliders.Length; i++)
{
if (colliders[i].gameObject != gameObject)
{
return true;
}
}
}
}
return false;
}