Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Reverse gravity

Discussion in 'Physics' started by plesasta_pevka, Jan 10, 2019.

  1. plesasta_pevka

    plesasta_pevka

    Joined:
    May 9, 2018
    Posts:
    2
    Greetings,

    I am fairly new to Unity so I am not sure whether this is the right place to search and ask for answers. However, me and my colleagues are working on a school project, developing a game which contains 2 worlds, the top one, which is normal and works fine and the bottom one, which is reversed, turned upside down and does not work appropriately. I have troubles implementing jump function for a character in the latter world - basic movement seems to work fine. I have tried to apply forces to an object, translating vectors but none of it seems to do its job. Also, the function “isGrounded” does nothing in specified context. So this is the main question: Which is the best way to get jump function to work?

    Thank you in advance!

    plesasta_pevka
     
  2. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    It depends on how you're doing your jumping. In my own code, jumping is just applying force along the player's 'transform.up' direction, and grounded check always involves a raycast in the player's '-transform.up' direction. Getting upside-down to work in your game should typically mean just reversing a few things.
     
  3. Belcherman

    Belcherman

    Joined:
    Jun 7, 2017
    Posts:
    30
    Here is one that works, you just have anything on the default layer and it is not jump able. Put things that you don't want to be jump on any other layer and it won't. You can change this non-jumping layer to anything you want.


    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class PlayerController3 : MonoBehaviour
    6. {
    7.     public LayerMask groundLayers;
    8.     public float speed = 5;
    9.     public float jumpForce = 10;
    10.     private Rigidbody rb;
    11.     private SphereCollider col;
    12.  
    13.     //BETTER JUMP
    14.     public float fallMultiplier = 2.5f;
    15.     public float lowJumpMultiplier = 2f;
    16.     //public float jumpStrength = 15f;
    17.     //public float jumpSpeed = 10f;
    18.     bool jumpPressed = false;
    19.  
    20.  
    21.  
    22.     void Start()
    23.     {
    24.         rb = GetComponent<Rigidbody>();
    25.         col = GetComponent<SphereCollider>();
    26.     }
    27.  
    28.     void Update()
    29.     {
    30.         float moveHorizontal = Input.GetAxis("Horizontal");
    31.         float moveVertical = Input.GetAxis("Vertical");
    32.  
    33.         Vector3 movement = new Vector3(moveHorizontal * speed * Time.deltaTime, 0, moveVertical * speed * Time.deltaTime);
    34.         rb.MovePosition(transform.position + movement);
    35.     }
    36.  
    37.  
    38.     void FixedUpdate()
    39.     {
    40.  
    41.         //Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);
    42.         //rb.AddForce(movement * speed);
    43.  
    44.         if (IsGrounded() && Input.GetKeyDown(KeyCode.Space))
    45.         {
    46.             rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    47.             jumpPressed = true;
    48.             //BetterJump();
    49.         }
    50.         else
    51.         {
    52.             jumpPressed = false;
    53.         }
    54.  
    55.  
    56.     }
    57.  
    58.     private bool IsGrounded()
    59.     {
    60.         return Physics.CheckCapsule(col.bounds.center, new Vector3(col.bounds.center.x, col.bounds.min.y, col.bounds.center.z), col.radius * .9f, groundLayers);
    61.     }
    62.  
    63.  
    64.     void BetterJump()
    65.     {
    66.  
    67.         //if (Input.GetKey(KeyCode.Space) && Grounded())
    68.         //{
    69.         //    jumpPressed = true;
    70.         //}
    71.         //else
    72.         //{
    73.         //    jumpPressed = false;
    74.         //}
    75.  
    76.         //Jump dynamics Code
    77.         if (rb.velocity.y < 0)
    78.         {
    79.             rb.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.fixedDeltaTime;
    80.         }
    81.         else if (rb.velocity.y > 0 && !jumpPressed)
    82.         {
    83.             rb.velocity += Vector3.up * Physics.gravity.y * (lowJumpMultiplier - 1) * Time.fixedDeltaTime;
    84.         }
    85.     }
    86.  
    87. }
     
    Last edited: Jan 14, 2019
  4. Would you mind put the code inside code tags? It's easier to read and to copy for everyone. Thanks!
     
  5. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    Like ninja said, please put it in tags so we can actually read it properly, I did saw this is there:
    Code (CSharp):
    1. rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
    2. j
    I don't think this would work if the world is upside down, maybe if you use the relative function.
    *didn't real all the code as it's hard w/o the tags.
     
  6. plesasta_pevka

    plesasta_pevka

    Joined:
    May 9, 2018
    Posts:
    2
    Thanks for all the answers guys. I've been experimenting with different methods and have found the most suitable for me.

    Code (CSharp):
    1. public class AlterPlayerMovement : MonoBehaviour
    2. {
    3.     public int health = 3;
    4.     public int coins = 0;
    5.     public float walkSpeed = 2f;
    6.     public float runSpeed = 6f;
    7.     float currentSpeed;
    8.     public float grav = -9.81f;
    9.     public float jumpHeight = 1;
    10.     float velY;
    11.     public float speedSmoothTime = 0.1f;
    12.     float speedSmoothVelocity;
    13.     [Range(1.0f, 1.125f)]
    14.     public float fallMult = 1.09f;
    15.  
    16.     public float info;
    17.     static public CharacterController controller;
    18.  
    19.     void Start()
    20.     {
    21.         controller = GetComponent<CharacterController>();
    22.  
    23.     }
    24.  
    25.     void Update()
    26.     {
    27.     }
    28.  
    29.     void FixedUpdate()
    30.     {
    31.         bool running = Input.GetKey(KeyCode.LeftShift);
    32.         Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), 0);
    33.         Vector2 inputDir = input.normalized;
    34.  
    35.         Move(inputDir, running);
    36.  
    37.         if (Input.GetKey(KeyCode.W))
    38.         {
    39.             Jump();
    40.         }
    41.  
    42.     }
    43.  
    44.     void Move(Vector2 inputDir, bool running)
    45.     {
    46.         info = velY;
    47.  
    48.         float targetSpeed = ((running) ? runSpeed : walkSpeed) * inputDir.x;
    49.         currentSpeed = Mathf.SmoothDamp(currentSpeed, targetSpeed, ref speedSmoothVelocity, speedSmoothTime);
    50.  
    51.         velY -= Time.deltaTime * grav;
    52.         if (velY < 0)
    53.         {
    54.             velY = velY * fallMult;
    55.         }
    56.         Vector3 velocity = transform.right * currentSpeed + Vector3.up * velY;
    57.  
    58.         controller.Move(velocity * Time.deltaTime);
    59.  
    60.         if (controller.isGrounded)
    61.         {
    62.             Debug.Log("On the floor.");
    63.             velY = 0;
    64.         }
    65.     }
    66.  
    67.     void Jump()
    68.     {
    69.         //if (controller.isGrounded)
    70.         //{
    71.             float jumpVelocity = Mathf.Sqrt(-2 * grav * jumpHeight);
    72.             velY = -jumpVelocity;
    73.         //}
    74.     }
    75. }
    Basically the code is the same as for the "normal" gravity concept. the only difference is the variable velY inside the Jump() function, which gets negative jumpVelocity value and later inside Move() function, where I decrement velY. Jumping seems to work now, but I have a problem with checking whether an object isGrounded. This does not seem to work with reversed world. I've tried rotating floor and object and nothing changes. Any ideas on how ti fix this?

    plesasta_pevka