I'm trying to make my 2D unity character jump - c#

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
}

Related

How can i make my character grounded in unity3d

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
}

Experiencing a weird collision bug between box colliders and tilemaps

This is my player movement code:
Footage of bug and inspector elements:
https://imgur.com/a/bmGqL1M
As you can see in this Imgur video, for some reason my player character, and also a pushable crate, can clip into this tilemap for a few pixels. I'm not quite sure why this is happening, since I've added a composite collider2D to the tilemap, to get rid of the very common "getting stuck in tilemap" bug, which isn't the case here, the clipping doesn't actually alter the movement in any way.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Header("Movement")]
[SerializeField] private float movementSpeed;
[SerializeField] private float jumpForce;
[Header("Jumping")]
private bool isGrounded;
[SerializeField] private Transform feetPos;
[SerializeField] private float checkRadius;
[SerializeField] private LayerMask whatIsGround;
[SerializeField] private float hangTime;
private float hangCounter;
private Rigidbody2D rb;
private SpriteRenderer sr;
private float moveX;
void Start()
{
rb = GetComponent<Rigidbody2D>();
sr = GetComponent<SpriteRenderer>();
}
void Update()
{
GetInput();
BetterJump();
}
void BetterJump()
{
isGrounded = Physics2D.OverlapCircle(feetPos.position, checkRadius, whatIsGround);
if (isGrounded)
{
hangCounter = hangTime;
} else
{
hangCounter -= Time.deltaTime;
}
if (hangCounter > 0 && Input.GetKeyDown(KeyCode.Space))
{
rb.velocity = Vector2.up * jumpForce;
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * .5f);
}
}
void FixedUpdate()
{
Move();
}
void Move()
{
rb.position += new Vector2(moveX, 0) * Time.deltaTime * movementSpeed;
}
void GetInput()
{
moveX = Input.GetAxisRaw("Horizontal");
if(moveX < 0)
{
sr.flipX = true;
}
else if (moveX > 0)
{
sr.flipX = false;
}
}
}

Unity collider touch not act on player

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'm trying to write a program for my character to jump. It is coming up with errors. I'm not quite sure how to fix them

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;
}

Moving Platforms

We are at very beginning of studying Unity, so we decided to create a mini-platformer. We've already made coins, platforms and character animation, but when we tried to animate a platform, a huge catastrophe appeared. The problem is that character can't stand on the platform. When the platform moves, he falls (it looks like there's no friction, but we tried to set one - it was helpless).
Maybe, we repeat the question, that have been asked before, but hope you'll help us to solve this paradox. Have a nice day ;)
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class CharControl : MonoBehaviour
{
public float maxSpeed = 10f;
private bool isFacingRight = true;
private Animator anim;
private bool isGrounded = false;
public Transform groundCheck;
private float groundRadius = 0.2f;
public LayerMask whatIsGround;
public Text scoreText;
public float score = 0;
private void Start()
{
anim = GetComponent<Animator>();
}
private void FixedUpdate()
{
isGrounded = Physics2D.OverlapCircle(groundCheck.position, groundRadius, whatIsGround);
anim.SetBool ("Ground", isGrounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
if (isGrounded && rigidbody2D.velocity.y != 0)
return;
float move = Input.GetAxis("Horizontal");
anim.SetFloat("Speed", Mathf.Abs(move));
rigidbody2D.velocity = new Vector2(move * maxSpeed, rigidbody2D.velocity.y);
if(move > 0 && !isFacingRight)
Flip();
else if (move < 0 && isFacingRight)
Flip();
}
private void Update()
{
if (isGrounded && (Input.GetKeyDown (KeyCode.Space) || Input.GetKeyDown(KeyCode.Joystick1Button0)))
{
anim.SetBool("Ground", false);
rigidbody2D.AddForce(new Vector2(0, 600));
}
}
private void Flip()
{
isFacingRight = !isFacingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
void OnTriggerEnter2D(Collider2D col){
if(col.gameObject.name == "Skull"){
score++;
Destroy (col.gameObject);
scoreText.text = "" + score;
}
if ((col.gameObject.name == "dead"))
Application.LoadLevel (Application.loadedLevel);
}}
you need to set MovingPlatform is ParentObject of HoldPlayerPlatform.
check below images for that also
Here is Holding Player Script on Moving Platform.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HoldPlayer : MonoBehaviour
{
private GameObject target = null;
private Vector3 offset;
void Start()
{
target = null;
}
void OnTriggerStay(Collider col)
{
target = col.gameObject;
offset = target.transform.position - transform.position;
}
void OnTriggerExit(Collider col)
{
target = null;
}
void LateUpdate()
{
if (target != null)
{
target.transform.position = transform.position + offset;
}
}
}
Here is image for setup HoldPlayerPlatform
Here is Setup for MovingPlatform

Categories