How do I limit a GameObject to jump only Once? - c#

I have Googled Everything but cannot get the right results. I want the GameObject to only jump once in the air, come back to the ground and then the player can jump. My current results are that the GameObject flies in the air if you press the spacebar. I wanna limit the GameObject to jump only once, come back and then jump if the player desires to. I have Shown some code down`
public class SphereController : MonoBehaviour
{
private bool IsOnGround = true;
Rigidbody rb;
public float BallSpeed = 10f;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
float Hmove = Input.GetAxis("Horizontal");
float Vmove = Input.GetAxis("Vertical");
Vector3 MoveBall = new Vector3(Hmove, 0f, Vmove);
rb.AddForce(MoveBall * BallSpeed);
if ((Input.GetKey(KeyCode.Space)) && IsOnGround == true)
{
rb.AddForce(0, 20, 0);
}
}
private void OnCollisionStay()
{
IsOnGround = true;
}

Change the IsOnGround to false.
if ((Input.GetKey(KeyCode.Space)) && IsOnGround)
{
rb.AddForce(0, 20, 0);
IsOnGround = false
}
You have the OnCollision method that changes it back to true so this should work fairly well.

So, the way I do it is the following.
STEPS:
1- Tag the floor object as whatever you like. I always tag it as ground. You tag objects in the Inspector window, at the top left. I says Untagged by default
2- This is the Code I write:
bool isGrounded;
void OnCollisionEnter(Collision other)
{
if(other.gameObject.tag == "ground")
{
isGrounded = true; // if its colliding with "ground", isGrounded is true
}
else
{
isGrounded = false;
}
if(Input.GetKeyDown(KeyCode.space) && isGrounded) // change space to whatever key to jump
{
Jump(); // your jump code goes here EG. Rigidbody.AddForce(0, 15, 0);
}
}
I hope this is helpful.

Related

Variable jump height in Unity jumping to random heights

I'm trying to implement a variable jump height system in my game. I stop the jump early by multiplying the velocity by .5f whenever the player releases the jump button (space).
This sometimes works, however sometimes it launches me up randomly when I lightly press space and let go as quickly as I can. It even jumps higher than the maximum jump height I get when I hold space.
This has happened in a project of mine so I thought the project had something wrong with it, I ended up making a new empty project just to test this out. I have no idea whats wrong. I can also confirm it's not an issue with onGround because I tried multiple ground sensing methods, and I substituted Input.GetKeyDown(KeyCode.Space) with Input.GetKey(KeyCode.Space) and nothing changed.
Here's the code :
Rigidbody2D rb;
[SerializeField] float force;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
bool jump;
[SerializeField] bool onGround;
void Update()
{
if(Input.GetKeyDown(KeyCode.Space) && onGround)
{
jump = true;
}
}
private void FixedUpdate()
{
if(jump)
{
//onGround = false;
jump = false;
rb.AddForce(Vector2.up * force, ForceMode2D.Impulse);
}
if(Input.GetKeyUp(KeyCode.Space) && rb.velocity.y > 0)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * .5f);
}
}
private void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.CompareTag("Ground"))
onGround = true;
}
private void OnCollisionExit2D(Collision2D other)
{
if(other.gameObject.CompareTag("Ground"))
onGround = false;
}
I have no other scripts attached. Thanks

A rope swing logic Unity

There is a player and a small ball in the middle of the level, the player can only jump, and when we press the spacebar again during the jump, he must look for a ball nearby and attach a rope to it, and swing, how can I do this? are there any sources or code?
private Rigidbody2D rb;
public float jumpforce;
public Transform grCheck;
public float grRadius = 0.2f;
private bool gr = false;
public LayerMask whatis;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
gr = Physics2D.OverlapCircle(grCheck.position, grRadius, whatis);
if (Input.GetKeyDown("space") && gr)
{
rb.AddForce(Vector3.up * jumpforce*100f);
}
}
First add a rigid body and a collider to the object. Write the following code in "FixedUpdate", it cannot be "Update", because it is a physical property, it must be "FixedUpdate"
transform.rotation = Quaternion.LookRotation(Vector3.forward, Vector3.up);
if (Input.GetButtonDown("Jump"))
{
if (ground == true)
{
//transform.Translate(new Vector3(Input.GetAxis("Horizontal")*distance, 2, Input.GetAxis("Vertical")*distance));
GetComponent<Rigidbody>().velocity += new Vector3(0, 5, 0);
GetComponent<Rigidbody>().AddForce(Vector3.up * mJumpSpeed);
ground = false;
Debug.Log("I am Pressing Jump");
}
}
"ground" is used to determine whether you are in the air or on the ground, and if it is in the air, of course, it will not let you jump. In addition, if you want to cancel the recoil, add "GetComponent().freezeRotation = true" in the "start" method;

Unity 2D - Jump Animation Reset

I'm new to the Unity world (2D) and I've run into some problems.
I have a script in which i want to jump. When i jump, the jump animation is super fast. You can only see it in the animator.
I have two other animations (Idle, Run) that work without any problems.
Can you please help me? :(
public class Player : MonoBehaviour
{
private Rigidbody2D rigid;
[SerializeField]
private float jumpForce = 5.0f;
private bool resetJump;
[SerializeField]
private float speed = 5.0f;
private PlayerAnimation playerAnim;
private SpriteRenderer playerSprite;
// Start is called before the first frame update
void Start()
{
...
}
// Update is called once per frame
void Update()
{
Movement();
}
void Movement()
{
float move = Input.GetAxisRaw("Horizontal");
Flip(move);
if (IsGrounded())
{
playerAnim.Jump(false);
}
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded() == true)
{
rigid.velocity = new Vector2(rigid.velocity.x, jumpForce);
StartCoroutine(ResetJumpNeededRoutine());
playerAnim.Jump(true);
}
rigid.velocity = new Vector2(move * speed, rigid.velocity.y);
playerAnim.Move(move);
}
void Flip(float move)
{
...
}
bool IsGrounded()
{
RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, Vector2.down, 0.3f, 1 << 8);
if (hitInfo.collider != null)
{
if (resetJump == false)
{
return true;
}
}
return false;
}
IEnumerator ResetJumpNeededRoutine()
{
yield return new WaitForSeconds(0.1f);
resetJump = false;
}
}
The problem is in ur code just after space is pressed the resetjump is getting false and isGrounded() is returning true and hence jump anim is getting false. So what i insist is to set trigger instead of setting playerAnim.jump use playerAnim.SetTrigger("Jump").
Study about animation trigger we use trigger to play animations like shoot and jump as these animation are true and then at next instant false.

I am trying to make an FPS soccer game using Unity, but my script isn't working

So, I am trying to create a soccer game from scratch... all I have done until now, is setting up the ball. This is how I want it to work: When the player collides with the ball, the ball jumps forward a bit. If you start running the ball will be pushed further away.
Now, here is my script for the ball (I am using the standard FPSController as character):
using UnityEngine;
using System.Collections;
public class BallController : MonoBehaviour {
private Rigidbody rb;
public GameObject character;
public float moveSpeed = 1000;
public float shootSpeed = 2000;
bool isTurnedUp = false;
bool isTurnedDown = false;
bool done = false;
// Use this for initialization
void Start () {
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
//Debug.Log(isTurnedUp + ", " + isTurnedDown);
switch (character.GetComponent<UnityStandardAssets.Characters.FirstPerson.FirstPersonController>().m_IsWalking)
{
case true:
if (isTurnedUp == false)
{
moveSpeed = moveSpeed / 1.4f;
isTurnedUp = true;
isTurnedDown = false;
}
break;
case false:
if (isTurnedDown == false)
{
moveSpeed = moveSpeed * 1.4f;
isTurnedDown = true;
isTurnedUp = false;
}
break;
}
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if (Vector3.Distance(gameObject.transform.position, character.transform.position) <= 5)
{
float distance = Vector3.Distance(gameObject.transform.position, character.transform.position);
}
}
}
void OnCollisionEnter(Collision collision) {
FixedUpdate();
if (done == false) {
rb.AddForce(Vector3.forward * moveSpeed, ForceMode.Impulse);
done = true;
}
else {
done = false;
}
}
//other
void OnDrawGizmosSelected()
{
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(transform.position, 2);
}
}
My problem is that the ball doesn't behave how I want it... it feels like it's about luck if the ball will jump forward when I touch it. Can someone tell me what I did wrong?
Inside of OnCollisionEnter you need to ensure the ball can only be kicked by the player. You can check whether or not the player has collided with the ball by checking the name or tag of the collision. The following example uses the name and assumes your player GameObject is named "Player".
Remove the done flag since this will only allow the player to kick the ball every other time they collide, and remove the FixedUpdate() call since FixedUpdate() is already called automatically every physics calculation.
Finally, if you want to kick the ball away from the player, then you need to calculate the direction away from the collision point instead of using Vector3.forward as seen below.
void OnCollisionEnter(Collision collision)
{
if(collision.gameObject.name == "Player")
{
Vector3 direction = (collision.transform.position - transform.position).normalized;
rb.AddForce(-direction * moveSpeed, ForceMode.Impulse);
}
}

Unity Click on 1 object to trigger another object

Please keep in mind that I'm new to Unity. I have 2 script that I want to "combline" but when I try then it don't Work.
I have a Script (Name : RobotController). This script controls the movement of the player. Up/Jump, Down, Left and Right. (This Works with Keyboard keys only atm)
This script Works just fine but now I want to add the feature of touch keys for phone. With this I mean that if a person click on the "up-Arrow" the player shall jump.
The Up-Arrow is an object.
This is were I get my problem. I have created the Up-Arrow with a collider and a script.
Up-Arrow script:
public class NewJumpScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnMouseOver()
{
if ((Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Began) || (Input.GetMouseButtonDown(0)))
{
Debug.Log("test");
}
}
}
Here is the RobotController script´, with ground check and so on.
public class RobotController : MonoBehaviour {
//This will be our maximum speed as we will always be multiplying by 1
public float maxSpeed = 2f;
public GameObject player;
public GameObject sprite;
//a boolean value to represent whether we are facing left or not
bool facingLeft = true;
//a value to represent our Animator
Animator anim;
//to check ground and to have a jumpforce we can change in the editor
bool grounded = true;
public Transform groundCheck;
public float groundRadius = 1f;
public LayerMask whatIsGround;
public float jumpForce = 300f;
private bool isOnGround = false;
void OnCollisionEnter2D(Collision2D collision) {
isOnGround = true;
}
void OnCollisionExit2D(Collision2D collision) {
anim.SetBool ("Ground", grounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
isOnGround = false;
}
// Use this for initialization
void Start () {
player = GameObject.Find("player");
//set anim to our animator
anim = GetComponent <Animator>();
}
void FixedUpdate () {
//set our vSpeed
//set our grounded bool
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
//set ground in our Animator to match grounded
anim.SetBool ("Ground", grounded);
float move = Input.GetAxis ("Horizontal");//Gives us of one if we are moving via the arrow keys
//move our Players rigidbody
rigidbody2D.velocity = new Vector3 (move * maxSpeed, rigidbody2D.velocity.y);
//set our speed
anim.SetFloat ("Speed",Mathf.Abs (move));
//if we are moving left but not facing left flip, and vice versa
if (move > 0 && !facingLeft) {
Flip ();
} else if (move < 0 && facingLeft) {
Flip ();
}
}
void Update(){
if ((isOnGround == true && Input.GetKeyDown (KeyCode.UpArrow)) || (isOnGround == true && Input.GetKeyDown (KeyCode.Space))) {
anim.SetBool("Ground",false);
rigidbody2D.AddForce (new Vector2 (0, jumpForce));
}
if (isOnGround == true && Input.GetKeyDown (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.2f, 0.2f);
}
if (isOnGround == true && Input.GetKeyUp (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.3f, 0.3f);
}
}
//flip if needed
void Flip(){
facingLeft = !facingLeft;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
What needs to happen is that when The "Up-arrow" in the game is clicked then The person shall jump on the same tearms as in the RobotController script.
I hope you understand my question.
Thanks for your time and help.
I posted this same answer to both of the questions, because they are so similar. You can easily modify the code to your needs.
This is only one way to do it. There are probably many more, but this is the best I have encountered so far.
On the QUI button, script like this is needed:
private Mover playerMover;
void Start()
{
playerMover = GameObject.Find("Character").GetComponent<Mover>();
}
void OnMouseOver()
{
if (Input.GetMouseButton(0))
{
Debug.Log("pressed");
playerMover.MoveButtonPressed();
}
}
Notice that find is only done ones in start function, because it is computationally heavy.
And on the Character gameobject, script component like this is needed:
using UnityEngine;
using System.Collections;
public class Mover : MonoBehaviour {
public void MoveButtonPressed()
{
lastPressedTime = Time.timeSinceLevelLoad;
}
public double moveTime = 0.1;
private double lastPressedTime = 0.0;
void Update()
{
if(lastPressedTime + moveTime > Time.timeSinceLevelLoad)
{
// Character is moving
rigidbody.velocity = new Vector3(1.0f, 0.0f, 0.0f);
}
else
{
rigidbody.velocity = new Vector3(0.0f, 0.0f, 0.0f);
}
}
}

Categories