Search Unity

Question Trying to stop force from acting on an object when it reaches upper bound

Discussion in 'Physics' started by zfried, Apr 19, 2023.

  1. zfried

    zfried

    Joined:
    Feb 23, 2023
    Posts:
    1
    Hello--I'm working on a challenge in Unity's Junior Programmer pathway that involves a floating balloon. The goal is to avoid floating bombs by tapping space to give the balloon lift (the balloon is affected by gravity).

    I've created an upper bound for the balloon so that it doesn't exceed a certain y value when I jump, but I'm finding that it'll get stuck at the top of the screen until (I assume) the upward force I've applied to it is outweighed by the force of gravity. I'm trying to reset the forces acting on it when it reaches the upper bound so that gravity immediately takes over.

    I've done some research on this (particularly this thread: https://forum.unity.com/threads/stop-forces-from-acting-on-object.615547/) and have found the following:

    -- Suggestions to set velocity and angular velocity to 0 (this hasn't worked)
    -- Suggestions to toggle the object inactive then active (this hasn't worked)

    Any tips? I'm a bit lost. Code below:

    public class PlayerControllerX : MonoBehaviour
    {
    public bool gameOver;

    public float floatForce;
    private float gravityModifier = 1.5f;
    private Rigidbody playerRb;
    public Vector3 playerVelocity;
    public Vector3 playerAngularVelocity;

    public ParticleSystem explosionParticle;
    public ParticleSystem fireworksParticle;

    private AudioSource playerAudio;
    public AudioClip moneySound;
    public AudioClip explodeSound;

    private float yRange = 14;
    private float yMin = 2;
    private bool isLowEnough = true;
    public bool tooLow;


    // Start is called before the first frame update
    void Start()
    {
    Physics.gravity *= gravityModifier;
    playerAudio = GetComponent<AudioSource>();
    playerRb = GetComponent<Rigidbody>();
    playerVelocity = GetComponent<Rigidbody>().velocity;
    playerAngularVelocity = GetComponent<Rigidbody>().angularVelocity;
    // Apply a small upward force at the start of the game
    playerRb.AddForce(Vector3.up * 5, ForceMode.Impulse);
    tooLow = false;
    }

    // Update is called once per frame
    void Update()
    {
    // While space is pressed and player is low enough, float up
    if (tooLow == false && transform.position.y < yMin)
    {
    gameOver = true;
    Debug.Log("Game Over!");
    explosionParticle.Play();
    playerAudio.PlayOneShot(explodeSound, 1.0f);
    tooLow = true;
    }
    if (Input.GetKey(KeyCode.Space) && !gameOver && transform.position.y < yRange && isLowEnough)
    {
    playerRb.AddForce(Vector3.up * floatForce);
    }
    //THIS IS WHERE I'VE BEEN WORKING
    if (transform.position.y >= yRange)
    {
    transform.position = new Vector3(transform.position.x, yRange, transform.position.z);
    playerVelocity = Vector3.zero;
    playerAngularVelocity = Vector3.zero;
    gameObject.SetActive(false);
    gameObject.SetActive(true);
    }

    }
     
  2. Reaktion

    Reaktion

    Joined:
    Nov 8, 2019
    Posts:
    53
    Hi,

    Please, if you leave code in forums, don't forget to use code section so that it's easier for everyone to read.

    Inside your code, you're storing the Player velocity & the Player angular velocity inside variables at start, but they are not a reference to them. You can change "playerVelocity" and "playerAngularVelocity" as much as you want, they'll never change the value of your Rigidbody velocity or angular velocity.
    What you need to do in order to change the velocity of a rigidbody is to get the component somewhere (like what you did with "playerRb"), and change it from here. Something like this :

    playerRb.velocity = Vector3.zero;


    You can also do this for the angular velocity, but since you're not adding Torque to it, and there is no natural torque value added to it, you don't need to.