I have a car in Unity and I want to make it jump. I only want it to jump when it is touching the ground. I was wondering how I can make a collision checker in the function I made. The isJumping is checking for a key being pressed in FixedUpdate()
Ground definition:
public GameObject ground;
Function so far:
private void HandleJumping()
{
if(isJumping==true){
transform.Translate (0f, 1f, 0f);
}
}
Well, there are multiple ways, here are some:
Check if the car has collided with the ground or not
void OnCollisionEnter(Collision collision) {
if(collision.gameObject == ground) {
isJumping = false;
}
}
Check if the velocity along Y-axis of the car is zero
If your car has a rigidbody component, check it's velocity along Y-axis is zero or not, if it is, that means the car is on the ground
if(gameObject.rigidbody.velocity.y == 0) {
isJumping = false;
}
Related
So I'm doing a game where the car automatically moves so whenever the car hits an object it continues floating in the air going forward without begin affected by gravity so that was my main code, I'm still kinda new to this :\
void Update()
{
transform.Translate(Vector3.forward * Speed * Time.deltaTime);
}
then I tried adding this to my code
void Start()
{
coll = GetComponent<Collider>();
coll.isTrigger = true;
}
// Disables gravity on all rigidbodies entering this collider.
void OnTriggerEnter(Collider other)
{
if (other.attachedRigidbody)
other.attachedRigidbody.useGravity = true;
}
but it's still not affected by this whatever I do it just doesn't work an continuously keeps going forward can you help me fix this problem I'm nearly done on that game so if you could help me I'd be very Thankful <3
Note:The car have RigidBody and is affected by gravity and have a huge mass but this doesn't affect any
Also make sure isKinematic is set to false.
void OnTriggerEnter(Collider other)
{
other.attachedRigidbody.useGravity = true;
other.attachedRigidbody.isKinematic = false;
}
void OnCollisionEnter(Collision col)
{
if(col.collider.CompareTag("taghere") || col.collider.name == "Name")
{
// you have to mention the script in which rigidbody you want to disable
}
}
When you add a rigidbody to a gameobject you are effectively handing over direct control of the translation to the rigidbody, and you should no longer alter the transform directly.
The easiest way would be to set the velocity of the plane you want to move in only
void FixedUpdate(){
rigidBody.velocity = new Vector3( speed.x, speed.y,rb.velocity.z);
}
I want the player to jump when the player is grounded.
private void OnTriggerStay(Collider other)
{
if(other.gameObject.layer == 8)
{
isGrounded = true;
}else { isGrounded = false; }
}
The player is on air when spawning. After the player falls to the Terrain, which has the tag Ground, isGrounded is still false. When I set isGrounded manually true and jump again, it's still true after collision. I also don't want the player to double jump in the air, which I probaly already coded but is not working because something is wrong.
Changing OnTriggerStay to OnTriggerEnter doesn't change something. I hope you can help me.
Do not use OnTriggerStay to do this. That's not guaranteed to be true very time.
Set isGrounded flag to true when OnCollisionEnter is called. Set it to false when OnCollisionExit is called.
bool isGrounded = true;
private float jumpForce = 2f;
private Rigidbody pRigidBody;
void Start()
{
pRigidBody = GetComponent<Rigidbody>();
}
private void Update()
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
pRigidBody.AddForce(new Vector3(0, jumpForce, 0));
}
}
void OnCollisionEnter(Collision collision)
{
Debug.Log("Entered");
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
void OnCollisionExit(Collision collision)
{
Debug.Log("Exited");
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = false;
}
}
Before you say it doesn't work, please check the following:
You must have Rigidbody or Rigidbody2D attached to the player.
If this Rigidbody2D, you must use OnCollisionEnter2D and
OnCollisionExit2D.
You must have Collider attached to the player with IsTrigger
disabled.
Make sure you are not moving the Rigidbody with the transform such
as transform.position and transform.Translate. You must move
Rigidbody with the MovePosition function.
Use this to check if collision is detected at all, it's good starting point for further debuging:
private void OnTriggerStay(Collider other)
{
Debug.Log(other);
}
You must have Collider attached to the player with IsTrigger disabled.
I think you mean enabled? I was struggling to get this to work but as soon as I enabled the collider's IsTrigger it started actually working. The OnTriggerEnter/Exit doesn't seem to do very much on a collider that isn't actually a trigger...
I am having an issue with my character which is not jumping at all. I am new to Unity, but I made sure to apply the script to the player and adjust the speed, I did not touch the Rigidbody 2D. If any one can help me figure our the issue, it will be much appreciated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float moveSpeed;
public float jumpSpeed;
public bool grounded = false;
private Rigidbody2D rb;
void Start() {
rb = GetComponent<Rigidbody2D>();
}
void Update () {
transform.Translate (Input.GetAxisRaw ("Horizontal") * moveSpeed * Time.deltaTime, 0, 0);
if (grounded)
{
if (Input.GetButtonDown ("Jump"))
{
rb.AddForce (Vector2.up * jumpSpeed);
grounded = false;
}
}
}
void OnCollisionEnter2D (Collision2D coll){
if (coll.transform.tag == "Ground")
{
grounded = true;
}
}
}
Inspector window of the Player GameObject
Inspector window of the Ground GameObject
Your problem is you haven't tag the Ground GameObject as so. So in the OnCollisionEnter2D the character detects the collision, but the if (coll.transform.tag == "Ground") will never be true. So it means the character can't be grounded
Since to be grounded is the first condition to check if the player pressed the Jump key. It is impossible it will ever jump
if (grounded)
{
if (Input.GetButtonDown ("Jump"))
{
rb.AddForce (Vector2.up * jumpSpeed);
grounded = false;
}
}
To solve this issue: You need to tag the Ground GameObject as so. In case you are not sure how to do that, on the Tag menu, create (if it doesnt exist already) a new tag called Ground. Then assign in that same menu the Ground Tag to the Ground GameObject. Here you can learn how in case you need a visual reference:
https://docs.unity3d.com/Manual/Tags.html
Edit: You can try this script if everything fails. It should work. I used my self some time ago, I cleaned the code so to leave only what you need to move the character in the x and y axis. Hope to have included everything you need:
public class CharacterController2D : MonoBehaviour {
// LayerMask to determine what is considered ground for the player
public LayerMask whatIsGround;
// Transform just below feet for checking if player is grounded
public Transform groundCheck;
// store references to components on the gameObject
Transform transform;
Rigidbody2D rigidbody;
bool isGrounded = false;
float vy;
float vx;
public float jumpForce = 600f;
void Awake () {
transform = GetComponent<Transform> ();
rigidbody = GetComponent<Rigidbody2D> ();
}
void Update()
{
// determine horizontal velocity change based on the horizontal input
vx = Input.GetAxisRaw ("Horizontal");
vy = rigidbody.velocity.y;
// Check to see if character is grounded by raycasting from the middle of the player
// down to the groundCheck position and see if collected with gameobjects on the
// whatIsGround layer
isGrounded = Physics2D.Linecast(transform.position, groundCheck.position, whatIsGround);
if(isGrounded && Input.GetButtonDown("Jump")) // If grounded AND jump button pressed, then allow the player to jump
{
DoJump();
}
// Change the actual velocity on the rigidbody
rigidbody.velocity = new Vector2(_vx * MoveSpeed, _vy);
}
//Make the player jump
void DoJump()
{
// reset current vertical motion to 0 prior to jump
vy = 0f;
// add a force in the up direction
rigidbody.AddForce (new Vector2 (0, jumpForce));
}
}
So things to take into account:
Instead of tag the ground, you create a layer with everything you
consider ground. That will include possible platforms the character
may jump over. Pass as a parameter this layer to the script in the
inspector
You need to place an empty GameObject in the feet of the character.
You will drag and drop that GameObject in the editor onto the
groundCheck public variable.
Instead of OnTriggerEnter, you will use Physics2D.Linecast which
will trave a line from the position of the character to under its
feet (where you should have place the Transform mentioned in the
previous step) and if in the middle there is an element of the
groundLayer, it means the character will be grounded.
Let me know if anything is not clear or if you find some bug.
As mentioned your problem is deffinetly that your missing to tag your ground object :)
A tip: What i like to do when i have problems like this is to use the unitys Debug.Log() to locate where the problem is it. It will let you know easily in the console what code is run and which is not. Try do the following:
void Update () {
transform.Translate (Input.GetAxisRaw ("Horizontal") * moveSpeed * Time.deltaTime, 0, 0);
if (grounded)
{
Debug.Log("Is grounded");
if (Input.GetButtonDown ("Jump"))
{
Debug.Log("Jump clicked");
rb.AddForce (Vector2.up * jumpSpeed);
grounded = false;
}
}
}
I want the player to jump when the player is grounded.
private void OnTriggerStay(Collider other)
{
if(other.gameObject.layer == 8)
{
isGrounded = true;
}else { isGrounded = false; }
}
The player is on air when spawning. After the player falls to the Terrain, which has the tag Ground, isGrounded is still false. When I set isGrounded manually true and jump again, it's still true after collision. I also don't want the player to double jump in the air, which I probaly already coded but is not working because something is wrong.
Changing OnTriggerStay to OnTriggerEnter doesn't change something. I hope you can help me.
Do not use OnTriggerStay to do this. That's not guaranteed to be true very time.
Set isGrounded flag to true when OnCollisionEnter is called. Set it to false when OnCollisionExit is called.
bool isGrounded = true;
private float jumpForce = 2f;
private Rigidbody pRigidBody;
void Start()
{
pRigidBody = GetComponent<Rigidbody>();
}
private void Update()
{
if (Input.GetButtonDown("Jump") && isGrounded)
{
pRigidBody.AddForce(new Vector3(0, jumpForce, 0));
}
}
void OnCollisionEnter(Collision collision)
{
Debug.Log("Entered");
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = true;
}
}
void OnCollisionExit(Collision collision)
{
Debug.Log("Exited");
if (collision.gameObject.CompareTag("Ground"))
{
isGrounded = false;
}
}
Before you say it doesn't work, please check the following:
You must have Rigidbody or Rigidbody2D attached to the player.
If this Rigidbody2D, you must use OnCollisionEnter2D and
OnCollisionExit2D.
You must have Collider attached to the player with IsTrigger
disabled.
Make sure you are not moving the Rigidbody with the transform such
as transform.position and transform.Translate. You must move
Rigidbody with the MovePosition function.
Use this to check if collision is detected at all, it's good starting point for further debuging:
private void OnTriggerStay(Collider other)
{
Debug.Log(other);
}
You must have Collider attached to the player with IsTrigger disabled.
I think you mean enabled? I was struggling to get this to work but as soon as I enabled the collider's IsTrigger it started actually working. The OnTriggerEnter/Exit doesn't seem to do very much on a collider that isn't actually a trigger...
I'm working on my very first Unity game. It's still in prototype and will be very simple anyways, consisting of a cube as the player and spheres as enemies.
I'm trying to write a code with AddForce to knock the player a pretty good distance in an arc in the direction opposite of the enemy when they come in contact, but I still have a primitive understanding of how to use AddForce and can't seem to get force applied in any direction at all. The player just moves through the enemy.
Here's the only thing I could manage to scrap together and it is obviously insufficient:
if (other.gameObject.tag == "Enemy")
{
playerDead = true;
Rigidbody rigidbody = other.GetComponent<Rigidbody> ();
rigidbody.AddForce (transform.forward * 100);
}
I can post a screenshot if it helps.
Instead of transform.forward, use a more tailored direction depending on the position of both units
public float speed = 100;
if (other.gameObject.tag == "Enemy")
{
playerDead = true;
Vector3 direction = (transform.position - other.transform.position).normalized;
other.GetComponent<Rigidbody>().AddForce (direction * speed);
}
Edit: You must make sure that the rigidbody is on the game object calling the OnCollisionEnter function, it cant just be on any of the objects involved in the collision.
I cannot comment so I must make an answer.
You have an isTrigger set up apparenty. Be sure to turn isTrigger OFF or your player will walk through the enemy collider.
[SerializeField]
private float speed = 100;
private bool playerDead;
OnCollisionEnter(Collision collision)
{
if(collision.gameObject.tag == "Enemy")
{
playerDead = true;
Vector3 direction = (transform.position - collision.transform.position).normalized;
collision.GetComponent<Rigidbody>().AddForce (direction * speed,0,0);
//AddForce is a vector3 apparently and requires (x,y,z)
// Also note that I'm getting errors with the "collision.GetComponent<>"
// You're going to want to remove "collision"
// I think the smarter approach maybe to declare a public Rigidbody variable ( Up Top )
[SerializeField]
private Rigidbody playerRidg;
playerRidg = GetComponent<Rigidbody>().AddForce(direction * speed,0,0);
}
}
My solution using coroutine which toggles a bool "spikes":
Player collision:
private void OnTriggerEnter2D(Collider2D collision){
if (collision.gameObject.tag == "Spike" )
{
StartCoroutine(Knockback());
}
}
Coroutine:
IEnumerator Knockback()
{
spikes = true;
yield return new WaitForSecondsRealtime(0.3f);
spikes = false;
}
Whenever the spikes bool is true player will be moved
void FixedUpdate()
{
if (spikes ==true)
{
Vector2 NewPosition = new Vector2(10.0f, 10.0f);
moveCharacter(NewPosition);
}
}