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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

2D physics bug - Descending platform throws character up into the air

Discussion in '2D' started by BlueWoozle, Aug 14, 2017.

  1. BlueWoozle

    BlueWoozle

    Joined:
    Mar 16, 2015
    Posts:
    8
    I'm trying to make a game where the player can drag a platform down that a character is stood on. If they drag slowly, the character moves with the platform, however if they drag quickly then the platform moves down and the character will fall on their own under gravity.

    I've almost got it working the way that I want, but sometimes when I pull the platform down quickly the character will get thrown upwards into the air (Seen at 8 seconds on the youtube video). There's another case when sometimes the character will get stuck/attached to the platform floating above the platform (seen at 27 seconds on the youtube video). I've zipped the whole project up and linked to it. Any help that anyone can give me would be greatly appreciated!

    Project zip here:
    https://drive.google.com/file/d/0B8_B9WY-uqSmelcxdzVsbl8wN1U/view?usp=sharing

    Video of the bugs here:


    The bug where the character is thrown upwards happens quite a lot, the second bug (where the character attaches above the platform) happens towards the end of the video.
     
  2. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    Just a heads up, most people on here will not be interested in downloading your whole project to help you. It would be best if you use code tags and paste the relevant classes into your post directly.
     
  3. BlueWoozle

    BlueWoozle

    Joined:
    Mar 16, 2015
    Posts:
    8
    Yeah, I thought that might be the case; I was trying to avoid people asking about what settings I had on the rigid bodies, or how I'd set the project up by uploading an archive.

    I'll post the 2 bits of source code!
     
  4. BlueWoozle

    BlueWoozle

    Joined:
    Mar 16, 2015
    Posts:
    8
    Character code:
    Code (CSharp):
    1. Transform myParent = null;
    2.     Transform myOriginalParent = null;
    3.     public float myTolerance = 0.5f;
    4.  
    5.     Vector3 myParentPreviousPosition;
    6.  
    7.     void Start ()
    8.     {
    9.         myOriginalParent = transform.parent;
    10.     }
    11.  
    12.     void LateUpdate()
    13.     {
    14.         if (myParent != null)
    15.         {
    16.             float delta = myParent.position.y - myParentPreviousPosition.y;
    17.             Debug.Log(delta);
    18.             myParentPreviousPosition = myParent.position;
    19.  
    20.             if (delta < -myTolerance)
    21.             {
    22.                 Detach();
    23.             }
    24.         }
    25.     }
    26.  
    27.     void OnCollisionEnter2D(Collision2D collision)
    28.     {
    29.         if (myParent == null)
    30.         {
    31.             Collider2D collider = collision.collider;
    32.             Attach(collider.transform);
    33.         }
    34.     }
    35.  
    36.     void Attach(Transform newParent)
    37.     {
    38.         myParent = newParent;
    39.         transform.parent = myParent;
    40.  
    41.         Rigidbody2D rigidbody = GetComponent<Rigidbody2D>();
    42.         rigidbody.isKinematic = true;
    43.         rigidbody.simulated = false;
    44.  
    45.         myParentPreviousPosition = myParent.position;
    46.     }
    47.  
    48.     void Detach()
    49.     {
    50.         myParent = null;
    51.         transform.parent = myOriginalParent;
    52.        
    53.         Rigidbody2D rigidbody = GetComponent<Rigidbody2D>();
    54.         rigidbody.isKinematic = false;
    55.         rigidbody.simulated = true;
    56.         rigidbody.MovePosition(transform.position);
    57.     }
     
  5. BlueWoozle

    BlueWoozle

    Joined:
    Mar 16, 2015
    Posts:
    8
    Platform code:

    Code (CSharp):
    1.     public Camera camera;
    2.  
    3.     void FixedUpdate()
    4.     {
    5.         Vector3 mousePosInWorldSpace = camera.ScreenToWorldPoint(Input.mousePosition);
    6.         Vector2 newPos = new Vector2(transform.position.x, mousePosInWorldSpace.y);
    7.         GetComponent<Rigidbody2D>().MovePosition(newPos);
    8.     }
     
  6. Deleted User

    Deleted User

    Guest

    You could do something like this and set the gravity scale to your liking
    Code (csharp):
    1.  
    2. public class Movement : MonoBehaviour {
    3.  
    4.     public float myTolerance = 5.0f;
    5.  
    6.     private bool attached;
    7.     private GameObject otherObject;
    8.     private Vector2 otherObjectPrevious;
    9.  
    10.  
    11.     void Start ()
    12.     {
    13.         attached = false;
    14.         otherObjectPrevious = Vector2.zero;
    15.     }
    16.  
    17.     void Update()
    18.     {
    19.         if (attached && otherObject != null)
    20.         {
    21.             transform.position = new Vector2(transform.position.x, otherObject.transform.position.y);
    22.             float delta = transform.position.y - otherObjectPrevious.y;
    23.             Debug.Log(delta);
    24.             otherObjectPrevious = new Vector2 (otherObject.transform.position.x, otherObject.transform.position.y);
    25.  
    26.             if (-delta < myTolerance)
    27.             {
    28.                 attached = false;
    29.             }
    30.            
    31.         }
    32.     }
    33.  
    34.     void OnCollisionEnter2D(Collision2D collision)
    35.     {
    36.         if (!attached)
    37.         {
    38.             attached = true;
    39.             otherObject = collision.gameObject;
    40.         }
    41.     }
    42.  
    43.     private void OnCollisionExit2D(Collision2D collision)
    44.     {
    45.         attached = false;
    46.         otherObject = null;
    47.     }
    48.  
    49. }
    50.  
     
  7. BlueWoozle

    BlueWoozle

    Joined:
    Mar 16, 2015
    Posts:
    8
    So would I use the attached variable to drive whether the character was being affected by gravity? At the moment I'm having the rigidbody simulate the gravity and I just attach/detach the character from the platform he's landed on.
     
  8. Deleted User

    Deleted User

    Guest

    instead of making the character a child of the platform you're just moving it up and down with the platform instead of letting it move based on physics so long as it's "attached"
     
  9. LiterallyJeff

    LiterallyJeff

    Joined:
    Jan 21, 2015
    Posts:
    2,802
    The hovering issue from your video is likely due to the character and platform colliding at high speeds, and then the character getting parented at a weird offset. I would advise using the Rigidbody setting "Collision Detection: Continuous" to get more accurate collision results at high speeds. Try that and see if it helps with your other issues related to physics.
     
  10. SAMEER-SPAS

    SAMEER-SPAS

    Joined:
    Nov 4, 2016
    Posts:
    1
    Did you check the physics material of your player? Maybe it is bouncy and jump up when fall from a height.
     
  11. Deleted User

    Deleted User

    Guest

    adding
    Code (csharp):
    1. rigidbody.velocity = Vector2.zero;
    to your detach function might have the effect you want.