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

Realistic 2D drag & drop physics like in the Little Inferno game?

Discussion in 'Physics' started by TwiiK, Nov 7, 2015.

Thread Status:
Not open for further replies.
  1. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I'm trying to recreate the drag & drop behavior seen in the Little Inferno game:


    Using a spring joint gets me 90% of the way there, but there's no way to fix the last 10%. :p

    My main problem is that the spring joint is way too springy no matter what settings I use. In Little Inferno it is rigid like a hinge joint when you drag the object around, but behaves like a soft spring joint if you drag the object through another object or against a wall. I can't use a hinge joint in Unity because the connected rigidbody doesn't respect collisions. If I drag the hinge joint through a solid wall the attached rigidbody just goes straight through the wall as if it wasn't there.

    I can fiddle with the dampening and frequency of the spring joint, but it's far too springy no matter what I do.

    Another problems is that the rigidbodies themselves behave like they're made of jello. I'm not sure if that's a PhysX problem or what. I've attached my entire project so you can see for yourself if you bother to take a look.

    And I'm not sure if PhysX can handle small objects, <10cm, or if there are settings I have to tweak for it to do so. In the attached project there's one scene where each block is 10x10cm and one scene where the blocks are 100x100cm. In the 10x10cm scene there are massive gaps between each block and everything looks rather wonky. Why is that? Must I use a bigger scale and higher gravity if I want to simulate small physics objects in Unity?

    I was thinking I need to use more than just one joint to simulate the behavior seen in Little Inferno. For example use a hinge joint when the object you're dragging isn't colliding with anything and switch to a spring joint when you detect a collision, or something like that. But I'm of course hoping someone here already has some experience to share with me. It feels very realistic in Little Inferno and I want to replicate that. It feels like you're holding the object and if you "squeeze" it into other objects or a solid wall it feels like you're doing so.

    Here's the script I currently have:
    Code (csharp):
    1. using UnityEngine;
    2.  
    3. public class Drag2d : MonoBehaviour {
    4.  
    5.     Vector3 inputPosition;
    6.     SpringJoint2D dragger;
    7.     bool isDragging = false;
    8.  
    9.     void Start() {
    10.         dragger = GameObject.Find("Drag2d").GetComponent<SpringJoint2D>();
    11.     }
    12.  
    13.     void Update() {
    14.         inputPosition = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    15.  
    16.         if (Input.GetMouseButtonDown(0) && !isDragging) {
    17.             Ray ray = GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
    18.             RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, Mathf.Infinity);
    19.  
    20.             if (hit.rigidbody != null) {
    21.                 dragger.connectedAnchor = hit.transform.InverseTransformPoint(GetComponent<Camera>().ScreenToWorldPoint(Input.mousePosition));
    22.                 dragger.connectedBody = hit.transform.GetComponent<Rigidbody2D>();
    23.                 dragger.enabled = true;
    24.                 isDragging = true;
    25.             }
    26.         }
    27.  
    28.         if (Input.GetMouseButton(0) && isDragging) {
    29.             dragger.transform.position = inputPosition;
    30.         }
    31.  
    32.         if (Input.GetMouseButtonUp(0) && isDragging) {
    33.             dragger.enabled = false;
    34.             isDragging = false;
    35.         }
    36.     }
    37. }
     

    Attached Files:

  2. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I was measuring the sizes of things inside Little Inferno based on the assumption that a credit card in the game is 86x54mm like in real life. And that would make the small wooden blocks and other objects 5x5cm or less. I tried making a 5x5cm object in unity, but the box collider 2d component returns:

    So I guess that answers it. It's not possible to use real world sizes inside Unity if you're dealing with very small objects. This is under the assumption that 1 unit is 1 meter.

    So I guess I have to scale everything up and increase gravity instead?
     
  3. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    We impose a 'limitation' that Box2D enforces which is limiting the minimum distance between vertex. This limit is the distance between vertex being no less than 0.0025 (2.5mm). When any vertex pair are closer than that then we drop the vertex, possibly resulting in not enough vertex and no collider being created; either way we issue the warning you refer to.

    If you're using 1 unit is meter then you are correct. However, 5cm is 0.05 and you won't get a warning using that value. Don't forget however that if you're using a transform scale, this affects the vertex separation.
     
  4. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Are you sure? I tried again and 5cm seems to be the absolute minimum I can do with the 2d box collider. If I reduce the size by just a fraction I get that error.

    The 3d box collider on the other hand can go much smaller it seems.

    But I'll fiddle with this to see what I get. I figured out that I have to reduce the "Min penetration for penalty" setting to get rid of the gaps between the 2d rigidbodies when I used small objects, but it still behaves a bit wonky. As if the squares aren't actually square. And when I try with bigger objects and an increased gravity to make it look like the objects are small they also behave weirdly, but in other ways. They don't collide like I would expect. Kind of hard to explain, but I guess there are other settings I need to mess with.

    I'm going to try with 3d physics as well seeing as there are so much fewer settings for that system. Less chance of me messing up. :p

    But this was kind of a detour anyway. I still haven't figured out how to handle the dragging properly.
     
  5. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    I'm sure because I did the Box2D integration. ;)

    The limit (0.0025)
    GoodSize.png

    Too small (0.0024):
    BadSize.png

    I presume you read my comment about transform scale and have checked that? The size of a collider is changed by the transform scale. Here there is no scaling.

    I'm not sure there are less settings in 3D. The gap between them is only visually significant depending on your viewing scale. There's nothing stopping you from reducing the size of the colliders with respect to the sprites/visuals or just using a larger viewing scale.
     
    pKallv likes this.
  6. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    I'm not getting your results for some reason.

    Here's two different approaches to creating a 5x5cm sprite, if I'm not completely mistaken. I haven't actually done much 2d work in Unity before. The grey box is a standard 1x1x1 unit cube as reference. The white box is my sprite.

    The sprite is just a 1x1 white pixel and in one example I have "pixels per unit" in the sprite importer set to the default 100 and in the other example I have it set to 1. But as you can see I'm not even able to have a 5x5cm 2d box collider now. This is a new project. In my other project 5x5cm works, but nothing under that. But I'm nowhere close to what you're showing.

    My Unity is up to date.

    test-1.png test-2.png
     
  7. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Here's an example with the transform scale set to 1 just to make it perfectly clear it's not working for me. No idea why I didn't just show this in the first place. :p

    This is in a new project so all the settings should be default.

    Edit: I'm on Windows 7 64-bit in case that's of any importance. Using Unity 5.2.2f1.

    test-3.png
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    Is this a root object i.e. it does not have a parent object in the hierarchy?

    It failing at default scaling of 1 is bizarre. I just don't see how that can even happen!

    Just for the record, the pixels-per-unit and sprite settings (or anything else) have nothing to do whatsoever with 2D physics. The size of the colliders are always what you set them to. The only other thing that affects them is the Transform component settings.
     
  9. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Yeah, I realized that. I haven't done much with 2d physics in Unity before now. :p

    Attached is a fresh project which has the problem for me. If I reduce the size of the box collider by any amount it stops working for me. Like 0.04999999 won't work, but 0.05 works.

    Edit: Should I just create a bug report for this? It is 100% reproducible for me, and seeing as what you're saying and what I'm getting is so different I may just postpone this 2d project until I find the root of the problem.
     

    Attached Files:

    Last edited: Nov 8, 2015
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    I'll take a look at it shortly, thanks.
     
  11. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    BTW: In the coming Unity 5.3 release, there are four new joints, one of which gives you exactly what you want here:

    TargetJoint2D

    You can make this joint soft or rigid. When rigid, it'll move to the target very abruptly, when soft it'll lag behind. In the demo it's set to be very soft though.
     
  12. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    So, the reason you're seeing this is because of a Box2D issue that was fixed in subsequent patch releases.

    Try downloading the latest 5.2.2 patch#3 release here and let me know if that fixes it for you.
     
  13. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    Lol, that's almost insulting. :p I have access to the beta so I guess I can try that out already.

    Thanks for everything. I'm at work now, but I'll check both Unity 5.3 and the patch when I get home.
     
    MelvMay likes this.
  14. TwiiK

    TwiiK

    Joined:
    Oct 23, 2007
    Posts:
    1,729
    The latest patch fixed the size issue with the 2d box colliders and the target joint in Unity 5.3 looks like it can give me what I want, but are those examples on your Youtube channel available anywhere? I didn't really understand the target joint at first, but I realized I have to add the joint to the rigidbody I click on which is opposite to the way I've been using the other joints for my rigidbody dragging.

    And what is a good way of doing it? I guess creating and destroying the component every time I click on a rigidbody isn't optimal. :p With the spring joint for example I just had one dragger object and if I clicked on a rigidbody I assigned it as the connected rigidbody for the joint.

    And the target joint doesn't support colliders without rigidbodies yet? The rigidbody goes through the collider as if it isn't there unless I add a rigidbody to it. I realize I don't know what's best or "most correct" between having a static object with just a collider or an object with both a collider and a rigidbody marked as kinematic, but I've always done the former. And I've never had any problems with it.
     
  15. Chintan-Kansagara

    Chintan-Kansagara

    Joined:
    Jul 16, 2016
    Posts:
    19
    hi
    i am 2d gameobject touch throw movement but collision not working
     
  16. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    Try looking at this project I'm working on (not finished yet by far). It has examples of all the joints including dragging motion.

    Look at this scene and a simple prefab that handles dragging with mouse-picking. That contains all you should need.
     
  17. Chintan-Kansagara

    Chintan-Kansagara

    Joined:
    Jul 16, 2016
    Posts:
    19
    Hi
    i am currant 2d game develop in 2d maze path solver game but fish character drag an path line to follow not perfect working.
    path check in raycast to hit time fish character move but not a smoothly movement fish character.
    plz hint me.

    My Code :
    void AA()
    {
    Debug.Log(456);
    Vector3 mousePos = Input.mousePosition;
    mousePos.z = 10;
    Vector3 screenPos = Camera.main.ScreenToWorldPoint(mousePos);

    RaycastHit2D[] hits;
    hits = Physics2D.GetRayIntersectionAll(Camera.main.ScreenPointToRay(Input.mousePosition),100);

    for(int i = 0; i < hits.Length ; i++)
    {


    if (hits != null /*&& hits != null && hits.collider != null && hits.collider.name.Contains(balloontype.name)*/)
    {
    if(hits.collider.tag == "Hero")
    {
    PlayerHit = true;
    }
    if(hits.collider.tag == "Wall")
    {
    WallHit = true;
    }
    else
    {
    WallHit = false;
    }

    //myHitList.Add(hits.collider.gameObject);
    }
    if(WallHit && PlayerHit == true)
    {
    gameObjectTodrag.transform.position = Vector3.Lerp(gameObjectTodrag.transform.position,hits.point,Time.deltaTime * 50f);
    }
    }
     
  18. davejones1

    davejones1

    Joined:
    Jan 19, 2018
    Posts:
    183
    Hi everyone, I am trying to make use of drag to limit the speed at which a UI slider can be moved. The slider is used to scrub through an animation. I want to limit the speed at which the UI slider can be moved so that the animation is played smoothly.
     
  19. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    Please use a new thread rather than adding to an existing one that isn't related to your question (apart from having "drag" in the title). ;) Thanks.
     
    davejones1 likes this.
  20. battleboy434

    battleboy434

    Joined:
    Mar 21, 2021
    Posts:
    1
    When I use the code on the top I get a next message



    Cannot create the 2D joint on 'Capsule' because it connects to itself.
     
  21. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,314
    Please do not hijack or necro threads. See Community Code of Conduct. I even said that above. o_O

    If you have a problem then then please create your own thread. That said, the error tells you exactly what is going wrong! You cannot connect a joint with itself.

    Also, I would suggest not just copying random code on the forums without understanding it then ask others why it's not working.
     
Thread Status:
Not open for further replies.