Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Jump is slightly offset

Discussion in 'Scripting' started by TiredOwlCreations, Feb 17, 2021.

  1. TiredOwlCreations

    TiredOwlCreations

    Joined:
    Jul 13, 2020
    Posts:
    2
    Hello! Let me start by saying I'm a complete beginner when it comes to unity and C#, so I have no idea what I'm doing. What I hope to achieve is a simple (3D) game where the player can choose to go left, right or forward using the arrow keys and depending on which key is pressed, the player will then 'hop' forward to the next platform in that direction.

    The code I'm currently using works almost completely, except that whenever I jump, the landing point is just slightly different from what I intend it to be. For example, if my starting point is (0, 4.06, 0) and I jump forward, my landing point would be something like (0, 4.06, 20.2) instead of exactly 20 on the Z-axis(?), which is the distance I want to jump. The same goes for jumping left and right. It works and the player moves, but it continues to move a bit further than I want it to. The difference also seems to build up, until eventually my player misses the platform completely after a few jumps. Is there a way to set the jump distance to exactly 20 (units I think) while still jumping in an arch?

    This is the code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. [RequireComponent(typeof(Rigidbody))]
    6. public class player : MonoBehaviour
    7. {
    8.     public Transform SpawnPoint;
    9.     public Vector3 jump;
    10.     public bool isGrounded;
    11.     Rigidbody rb;
    12.      
    13.     void Start()
    14.     {
    15.         //Calls the Rigidbody
    16.         rb = GetComponent<Rigidbody>();
    17.     }
    18.  
    19.     void OnCollisionEnter(Collision theCollision)
    20.     {
    21.         //This is so the player won't slide further after making contact with any object
    22.         rb.velocity = new Vector3(0.0f,0.0f,0.0f);
    23.        
    24.         //Checks to see if there is contact with the objects tagged "Floor"
    25.         if(theCollision.gameObject.tag == "Floor" )
    26.         {
    27.             isGrounded = true;
    28.             Debug.Log("Grounded");
    29.         }
    30.         // If player makes contact with RespawnPlatform, player will return the given position
    31.         if(theCollision.gameObject.tag == "Respawn")
    32.         {
    33.             transform.position = SpawnPoint.position;
    34.             Debug.Log("Respawn!");
    35.         }
    36.       }
    37.  
    38.     void OnCollisionExit(Collision theCollision)
    39.     {
    40.         //Checks if there is still contact with objects tagged "Floor"
    41.         if(theCollision.gameObject.tag == "Floor")
    42.         {
    43.             isGrounded = false;
    44.         }
    45.     }
    46.      
    47.     void Update()
    48.     {
    49.            
    50.         if(Input.GetKeyDown("up") && isGrounded)
    51.         {
    52.             jump = new Vector3(0.0f, 10.0f, 10.0f);  
    53.             rb.AddForce(jump, ForceMode.Impulse);
    54.             isGrounded = false;
    55.             Debug.Log("Jumped");
    56.  
    57.         }
    58.         else if(Input.GetKeyDown("left") && isGrounded)
    59.         {
    60.             jump = new Vector3(-10.0f, 10.0f, 10.0f);  
    61.             rb.AddForce(jump, ForceMode.Impulse);
    62.             isGrounded = false;
    63.             Debug.Log("Jumped");
    64.  
    65.         }
    66.         else if(Input.GetKeyDown("right") && isGrounded)
    67.         {  
    68.             jump = new Vector3(10.0f, 10.0f, 10.0f);  
    69.             rb.AddForce(jump, ForceMode.Impulse);
    70.             isGrounded = false;
    71.             Debug.Log("Jumped");
    72.         }
    73.        
    74.     }
    75. }
    76.  
     
  2. calpolican

    calpolican

    Joined:
    Feb 2, 2015
    Posts:
    400
    By using AddForce you're using the physics engine to calculate the body's position.
    Sometimes when you need so much precision, instead of using the phyisics engine you'd use a premade animation that gives you full control of everything. You can do one in the animation window by laying keyframes and such, or in another app like blender, or you can make one by code, say using a breziere curve and such.
    For your case, and since you're almost hitting the right target, I'd stick with the phyisics engine (also I don't know if you want to use the phyisics engine for something particular). So, I'd make public the values of you jump vector and I'd manually change them to make the error almost non existing for all cases, by trial an error. Say, if a force of 10.0f gives you a Z value forward of 20.2 with an offset in z of 0.2f, then I'd try a force in Z of 9.901f. The idea is to try to minimize the error. Also, I'd check if there's no friction involved, and such.
    In any case, when the error is minimal, and it's almost invisible for the naked eye, what I'd do is, after each jump I'd snap or lerp the character to the right position by code, otherwise the offset introduce by the error will eventually add up enought to become obvious and your character will hit off the tails after a certain amount of movements. So, if he lands at 20.00001, I'd change it's position to 20 by code.
    You can try using a trajectory formula to minimiza the error:
    https://www.omnicalculator.com/physics/trajectory-projectile-motion
     
    Last edited: Feb 17, 2021
    TiredOwlCreations likes this.
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Definitely ditch the rigidbody physics if your goal is to move in deterministic fashion from platform to platform like Frogger or something, for reasons @calpolican mentioned.

    Use something like Vector3.MoveTowards instead.
     
  4. TiredOwlCreations

    TiredOwlCreations

    Joined:
    Jul 13, 2020
    Posts:
    2
    I've chosen to snap my player into place and it works for me. Thanks!