- Home /
 
2D Platformer with custom physics Object - jumping issue
Hello there :)
I am quite new to unity and coding in general and I am working currently on a 2D-Super-Mario-Like-Platformer Game. I have build an own physics Object with this Unity Tutorial (https://www.youtube.com/playlist?list=PLX2vGYjWbI0SUWwVPCERK88Qw8hpjEGd8) , because it looked promising for exactly the purpose i needed.
Unfortunately I have one issue with my jumping control: When the player jumps and lands on the same level (from Ground to Ground) it behaves as intended. But when i jump on a higher level (e.g. a Plattform) my Player does make another small jump right after landing. As far as I have seen it in a small scene in the youtube Video, the tutor had the very same issue there, but did not notice (or mention) it.
I assume the issue is burried somewhere in the physics Object:
 public float minGroundNormalY = 0.65f;
 public float gravityModifier = 1f;
 public Vector2 targetVelocity;
 public bool grounded;
 protected Vector2 groundNormal;
 public Vector2 velocity;
 protected Rigidbody2D rb2d;
 protected ContactFilter2D contactFilter;
 protected RaycastHit2D[] hitBuffer = new RaycastHit2D[16];
 protected List<RaycastHit2D> hitbufferList = new List<RaycastHit2D> (16);
 protected const float minMoveDistance = 0.001f;
 protected const float shellRadius = 0.01f;
 private void OnEnable()
 {
     rb2d = GetComponent<Rigidbody2D>();
 }
 // Start is called before the first frame update
 void Start()
 {
     contactFilter.useTriggers = false;
     contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
     contactFilter.useLayerMask = true;
     groundNormal = new Vector2(0f, 1f);
 }
 // Update is called once per frame
 void Update()
 {
     targetVelocity = Vector2.zero;
     ComputeVelocity();
 }
 protected virtual void ComputeVelocity()
 {
 }
 private void FixedUpdate()
 {
     velocity += gravityModifier * Physics2D.gravity * Time.deltaTime;
     velocity.x = targetVelocity.x;
     grounded = false;
     Vector2 deltaPosition = velocity * Time.deltaTime;
     Vector2 moveAlongGround = new Vector2(groundNormal.y, -groundNormal.x);
     Vector2 move = moveAlongGround * deltaPosition.x;
     Movement(move, false);
     move = Vector2.up * deltaPosition.y;
     Movement(move, true);
 }
 public void Movement(Vector2 move, bool yMovement)
 {
     float distance = move.magnitude;
     if (distance > minMoveDistance)
     {
         int Count = rb2d.Cast(move, contactFilter, hitBuffer, distance + shellRadius);
         hitbufferList.Clear();
         for (int i = 0; i < Count; i++)
         {
             hitbufferList.Add(hitBuffer[i]);
         }
         for (int i = 0; i < hitbufferList.Count; i++)
         {
             Vector2 currentNormal = hitbufferList[i].normal;
             if (currentNormal.y > minGroundNormalY)
             {
                 grounded = true;
                 if (yMovement)
                 {
                     groundNormal = currentNormal;
                     currentNormal.x = 0;
                 }
             }
             float projection = Vector2.Dot(velocity, currentNormal);
             if (projection < 0)
             {
                 velocity = velocity - projection * currentNormal;
             }
             float modifiedDistance = hitbufferList[i].distance - shellRadius;
             distance = modifiedDistance < distance ? modifiedDistance : distance;
         }
     
     }
     rb2d.position = rb2d.position + move.normalized * distance;
 }
 
               But maybe it is within my player controller:
 public float maxSpeed = 7;
 public float jumpTakeOffSpeed = 7;
 public bool isGrounded = false;
 private SpriteRenderer spriteRenderer;
 private Animator animator;
 public AudioSource jumpSmall;
 public AudioSource jumpBig;
 void Awake()
 {
     spriteRenderer = GetComponent<SpriteRenderer> ();
     animator = GetComponent<Animator> ();
 }
 protected override void ComputeVelocity()
 {
     Vector2 move = Vector2.zero;
     move.x = Input.GetAxis("Horizontal");
     animator.SetFloat("Speed", Mathf.Abs(move.x));
     if (Input.GetButtonDown("Jump") && grounded)
     {
             velocity.y = jumpTakeOffSpeed;
         jumpBig.Play();
     }
     else if (Input.GetButtonUp("Jump"))
     {
         if (velocity.y > 0)
             velocity.y *= 0.5f;
     }
     bool flipSprite = (spriteRenderer.flipX ? (move.x > 0.01f) : (move.x < -0.01f));
     if (flipSprite)
     {
         spriteRenderer.flipX = !spriteRenderer.flipX;
     }
     targetVelocity = move * maxSpeed;
 }
 
               I am completely lost and any help would be very much appreciated :) Thanks Folks!
if you are new to all this you really should just use standard unity stuff, this code looks really over complicated. A rigidbody has its own velocity, gravity everything.. what you did here was reinvent the wheel.. Sometimes people want to do that.. I implemented my own gravity.. but I built it on unity physics..
Hi, thanks for the answer! True, i also thought of leaving all this custom stuff behind and working only with the basic unity stuff. But on the other hand, i really want my game to feel like a 2d Plattformer game and i have read several threads, that it is not the best idea for those games to rely on basic unity 2d physics.
Your answer