Player not jumping. Unity RigidBody2D - c#

When I press my jump key, the player doesn't jump but the Debug message I added does print in console.
My code:
using UnityEngine;
public class PlayerController : MonoBehaviour
{
// Start is called before the first frame update
private Transform transform;
private Rigidbody2D rb;
private bool onground = false;
public float speed;
public float momentum;
public float jumpForce;
void Start()
{
rb = gameObject.GetComponent<Rigidbody2D>();
transform = rb.transform;
}
// Update is called once per frame
void Update()
{
}
private void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
Vector3 movement = new Vector3(moveHorizontal, 0, 0);
transform.position += movement * Time.deltaTime * speed;
if (Input.GetButtonDown("Jump") && onground)
{
Jump(jumpForce);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.collider.tag == "Floor")
{
onground = true;
Debug.Log("Player Is On Ground!");
}
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.collider.tag == "Floor")
{
onground = false;
Debug.Log("Player Is Not On The Ground!");
}
}
private void Jump(float force)
{
rb.velocity = Vector2.up * force * Time.deltaTime;
Debug.Log("Player Has Jumped!");
}
}
the player can move but not jump and haven't found any posts anywhere with a similar issue, I might not be looking hard enough or searching the correct thing but I just cannot find a solution to my problem.

First of all, you move the player by transform component but trying to jump by physics (rigidbody), it isn't a good idea and I recommend you to work only with rigidbody in this case. Also the multiply jump force by Time.deltaTime doesn't have a sense because you call the method from FixedUpdate(), I assume that the power of jump is too week to see the result so try to remove Time.deltaTime and increase the jumpForce value.

Related

Sprite not Appearing in Unity 2D Game

I'm creating a 2D Top Down game for practice and I need a little bit of help. For context, it's a 2D Top Down Shooter game, where you can move and shoot enemies. The enemies have a basic radius system where if the player gets within the radius, it'll approach the player.
Now I'm making a game mechanic where the player can hide in a cardboard box, the player can press 'E' and he'll suddenly become a cardboard box, where if the player is in the cardboard box, the enemy doesn't detect him even if the player's within the radius. Yes, just like in Metal Gear. Now I've created the prefabs and everything and functionality-wise, it works perfectly. If you press 'E' the enemy cannot detect you.
Now the small problem is that the cardboard box didn't appear, so it's just the player disappearing entirely. I do not know what caused this problem.
For context, these are my scripts. Feel free to read them, or not :)
PlayerController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
public GameObject bulletPrefab;
public GameObject player;
private Rigidbody2D rb2d;
private Vector2 moveDirection;
[SerializeField] private Camera cam;
[SerializeField] private GameObject gunPoint;
public bool isHiding = false;
[SerializeField] private GameObject cardboardBox;
[SerializeField] private GameObject gunSprite;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
cardboardBox.SetActive(false); // Hide the cardboard box when the game starts
gunSprite.SetActive(true); // Show the gun sprite when the game starts
}
// Update is called once per frame
void Update()
{
CheckCursor();
ProcessInputs();
// Make the camera follow the player
cam.transform.position = new Vector3(player.transform.position.x, player.transform.position.y, cam.transform.position.z);
// Check if player pressed the "E" key to toggle the cardboard box
if (Input.GetKeyDown(KeyCode.E))
{
isHiding = !isHiding; // Toggle the isHiding variable
cardboardBox.SetActive(isHiding); // Show/hide the cardboard box accordingly
// If player is hiding, stop player movement
if (isHiding)
{
moveDirection = Vector2.zero;
player.GetComponent<SpriteRenderer>().enabled = false;
cardboardBox.GetComponent<SpriteRenderer>().enabled = true;
gunSprite.SetActive(false); // Hide the gun sprite when the player is hiding
}
else
{
player.GetComponent<SpriteRenderer>().enabled = true;
cardboardBox.GetComponent<SpriteRenderer>().enabled = false;
gunSprite.SetActive(true); // Show the gun sprite when the player is not hiding
}
}
}
private void FixedUpdate()
{
if (!isHiding) // Only allow player to move if they are not hiding in the cardboard box
{
Movement();
}
}
private void CheckCursor()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 characterPos = transform.position;
if (mousePos.x > characterPos.x)
{
this.transform.rotation = new Quaternion(0, 0, 0, 0);
}
else if (mousePos.x < characterPos.x)
{
this.transform.rotation = new Quaternion(0, 180, 0, 0);
}
}
private void Movement()
{
// TODO : Implementasi movement player
rb2d.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
}
private void ProcessInputs()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY);
if (Input.GetMouseButtonDown(0))
{
Shoot();
}
}
private void Shoot()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 gunPointPos = gunPoint.transform.position;
Vector3 direction = (mousePos - gunPointPos).normalized;
GameObject bullet = Instantiate(bulletPrefab, gunPointPos, Quaternion.identity);
bullet.GetComponent<Bullet>().Init(direction);
}
}
EnemyController script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public Transform player;
public float moveSpeed = 5f;
public float detectionRadius = 5f;
public int maxHealth = 1;
private int currentHealth;
private Rigidbody2D rb2d;
private Vector2 movement;
private void Start()
{
rb2d = this.GetComponent<Rigidbody2D>();
currentHealth = maxHealth;
}
private void Update()
{
float distanceToPlayer = Vector2.Distance(transform.position, player.position);
if (player != null && distanceToPlayer <= detectionRadius && !player.GetComponent<PlayerController>().isHiding)
{
Vector3 direction = player.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb2d.rotation = angle;
direction.Normalize();
movement = direction;
}
else
{
movement = Vector2.zero;
}
}
void FixedUpdate()
{
moveCharacter(movement);
}
private void moveCharacter(Vector2 direction)
{
rb2d.MovePosition((Vector2)transform.position + (direction * moveSpeed * Time.deltaTime));
}
public void DestroyEnemy()
{
Destroy(gameObject);
}
}
Bullet script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField] private float speed;
[SerializeField] private Vector3 direction;
public void Init(Vector3 direction)
{
this.direction = direction;
this.transform.SetParent(null);
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg);
}
// Update is called once per frame
void Update()
{
this.transform.position += transform.right * speed * Time.deltaTime;
}
// TODO : Implementasi behaviour bullet jika mengenai wall atau enemy
private void OnTriggerEnter2D(Collider2D other)
{
switch(other.gameObject.tag)
{
case "Wall":
Destroy(gameObject);
break;
case "Enemy":
Destroy(gameObject);
other.gameObject.GetComponent<EnemyController>().DestroyEnemy();
break;
}
}
}
I've tried tinkering my scripts, I've tried checking if there are any missing components in the cardboard box game object but to no avail. Although I might be wrong on the Unity part since I'm fairly certain that the script isn't the problem here, again might be wrong.
I appreciate all the help I can get, thank you for reading until here

Player now does not jump after adding health in Unity

so first time learning C# for my team studio class. I found this video which I was able to get my player moving and jumping perfectly, https://www.youtube.com/watch?v=3GtQ2yQX2kU&t=569s however after I added a health/can die system to the script, now the player refuses to jump no matter what I do. Since I am a newbie at this, I am just going to post the whole thing here if anyone can point me in the right direction. I've played with the box colliders, added the layers to the platforms like the tutorial said... please, if anyone can help. I know I'm a newbie to this :(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public HealthBar healthBar; //Communicates with the healthbar script
public float moveSpeed;
public float jumpForce;
public int jumpsAmount;
int jumpsLeft;
public Transform GroundCheck;
public LayerMask GroundLayer;
public int maxHealth = 3;
public int currentHealth;
bool isGrounded;
float moveInput;
Rigidbody2D rb2d;
float scaleX;
// Start is called before the first frame update
void Start()
{
healthBar.SetMaxHealth(maxHealth); //Sets healthbar to max health
currentHealth = maxHealth;
rb2d = GetComponent<Rigidbody2D>();
scaleX = transform.localScale.x;
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
if (currentHealth <= 0) //When Health is zero the player is destroyed
{
Destroy(gameObject);
}
healthBar.SetHealth(currentHealth); //Updates Healthbar when damgage is taken
}
// Update is called once per frame
void Update()
{
moveInput = Input.GetAxisRaw("Horizontal");
Jump();
}
private void FixedUpdate()
{
Move();
}
public void Move()
{
Flip();
rb2d.velocity = new Vector2(moveInput * moveSpeed, rb2d.velocity.y);
}
public void Flip()
{
if (moveInput > 0)
{
transform.localScale = new Vector3(scaleX, transform.localScale.y, transform.localScale.z);
}
if (moveInput < 0)
{
transform.localScale = new Vector3((-1) * scaleX, transform.localScale.y, transform.localScale.z);
}
}
public void Jump()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CheckIfGrounded();
if (jumpsLeft > 0)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
jumpsLeft--;
}
}
}
public void CheckIfGrounded()
{
isGrounded = Physics2D.OverlapCircle(GroundCheck.position, GroundCheck.GetComponent<CircleCollider2D>().radius, GroundLayer);
ResetJumps();
}
public void ResetJumps()
{
if (isGrounded)
{
jumpsLeft = jumpsAmount;// jumpsAmount =2;
}
}
}
I put the groundcheck collider where the video wanted me to, even played around having different locations too. Nothing is working... tried changing the jump force too to see if it needs to be higher. I am at a complete loss.

unity onCollisionEnter2D is not working, how can I get it to work?

my bird is colliding with the clouds but it only moves them and doesn't trigger it
my character
public float jumpForce = 5f;
public float gravity = -9.81f;
public GameObject gus;
public Transform rotation_checker;
public Transform chekced;
float velocity;
void Start()
{
}
// Update is called once per frame
void Update()
{
gameObject.transform.eulerAngles = new Vector2(0,0);
velocity += gravity * Time.deltaTime;
if (Input.GetKeyDown(KeyCode.W))
{
velocity = jumpForce;
}
rotation_checker.position = chekced.position;
transform.Translate(new Vector2(0, velocity) * Time.deltaTime);
}
private void OnTriggerExit2D(Collider2D collider)
{
Debug.Log(collider.gameObject);
if(collider.gameObject.name == "skybluscene")
{
Destroy(gameObject);
}
}
private void onCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "cloud")
{
Destroy(gameObject);
}
}
the cloud
float x = -4f;
void Start()
{
}
// Update is called once per frame
void Update()
{
gameObject.transform.Translate(new Vector2(x, 0) * Time.deltaTime);
}
void OnTriggerExit2D(Collider2D collider)
{
if ( collider.gameObject.tag == "scene")
{
Destroy(gameObject);
}
}
cloud works just fine, it destroys itself when it leaves the scene but bird doesn't destroy itself when it collides with the cloud
both bird and cloud have dynamic rigidbody2d and a collider
First of all: On your character script, your onCollisionEnter2D is misspelled. It needs to start with a capital letter.
Second: all your other methods use tags to identify what GameObject they collided with, but "skybluscene" (which also looks like a typo) is identified by its gameObject name.
Third: I'm not sure, but I find it odd that you're using both triggers and collisions in the same script.

How do I stop infinite jumping in 2D unity?

so I started unity literally yesterday meaning this is my second day. I followed a tutorial to make a movement script, but when I continuously press space, I can jump like infinitely. This is my code below, is there any way to fix the infinite jump to just two jumps and then it resets when it hits the ground?
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float speed;
private Rigidbody2D body;
private void Awake()
{
body = GetComponent<Rigidbody2D>();
}
private void Update()
{
body.velocity = new Vector2(Input.GetAxis("Horizontal") * speed, body.velocity.y);
if (Input.GetKey(KeyCode.Space))
body.velocity = new Vector2(body.velocity.x, speed);
}
}
You can prevent this by adding time delay
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
[SerializeField] private float speed;
[SerializeField] private float jumpTimeDelay = 0.5f; // feel free to increase or decrease
private const float timeDelayConst = jumpTimeDelay;
private bool isGrounded = false;
private Rigidbody2D body;
private void Awake() {
body = GetComponent<Rigidbody2D>();
}
private void Update(){
body.velocity = new Vector2(Input.GetAxis("Horizontal") * speed,
body.velocity.y);
isGrounded = jumpTimeDelay <= 0;
jumpTimeDelay -= Time.time;
if (Input.GetKey(KeyCode.Space) && isGrounded){
body.velocity = new Vector2(body.velocity.x, speed);
jumpTimeDelay = timeDelayConst;
}
}
}
This is easily done by adding a boolean value to check if the player is grounded or not and change the value when player jumps. You also need to add a tag to your ground object so we can check if the player is touching the ground. To add tags to objects please refer to Unity - Manual: https://docs.unity3d.com/530/Documentation/Manual/Tags.html
Just for future these kind of questions are asked a lot so you can pretty much google your question and find similar answers.
public class PlayerMovement : MonoBehaviour
{
[SerializeField] private float speed;
private Rigidbody2D body;
private bool isGrounded = true;
private void Awake()
{
body = GetComponent<Rigidbody2D>();
}
private void Update()
{
body.velocity = new Vector2(Input.GetAxis("Horizontal") * speed, body.velocity.y);
if(Input.GetKey(KeyCode.Space))
{
if (isGrounded)
{
isGrounded = false;
body.velocity = new Vector2(body.velocity.x, speed);
}
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.tag == "Ground") {
isGrounded = true;
}
}
}

Object not touching ground when moving platform is falling in Unity

I'm using Unity to make my character jump from a moving platform where it goes up & down infinitely. The problem I'm facing is when the moving platform goes up, the jump is working perfectly but when the platform is going down, my character can't jump most often & I can see the platform is "vibrating" a bit which is weird.
Here are my codes:
Moving Platform Script [NB - Rigidbody2D is set to Kinematic]
public class Moveground : MonoBehaviour
{
[SerializeField] private Transform posTop, posBot;
private float maxTop = -0.5f;
private float maxBot = -5.0f;
[SerializeField] private float speed;
[SerializeField] private Transform startPos;
private Vector2 nextPos;
private void Start()
{
nextPos = startPos.position;
}
private void FixedUpdate()
{
if (transform.position == posTop.position)
{
nextPos = posBot.position;
}
if (transform.position == posBot.position)
{
nextPos = posTop.position;
}
transform.position = Vector2.MoveTowards(transform.position, nextPos, speed*Time.deltaTime);
}
}
PlayerController.cs (Only Jump part)
[SerializeField] private LayerMask ground;
private Collider2D coll;
private void Start()
{
coll = GetComponent<Collider2D>();
}
private void Update()
{
InputManager();
}
private void InputManager()
{
if (Input.GetButtonDown("Jump") && coll.IsTouchingLayers(ground)) // Moving Platform's layer is also "ground"
{
Jump();
}
}
private void Jump() {
rb.velocity = new Vector2(rb.velocity.x, jumpforce); // jumpforce is a float number
}
How can I resolve this issue? I'm new to Unity.
Instead of "IsTouchingLayers" try something like this in the PlayerController class:
public bool IsGrounded()
{
return Physics2D.Raycast(transform.position, Vector3.down, 0.1f, ground);
}
and play around with the distance argument, which is the 0.1f one.
If your player transform is not at the bottom of the player, you can also put in something like this instead of 0.1f:
coll.bounds.extents.y + 0.1f

Categories