How to Use Hinges for Sway?

I’m trying to make the items collected on this magnet,

Sway to the sides based on the rotation of the magnet. I thought this would be fairly basic, I just added a hinge to the collected item, and on collect, it sets the connected rigidbody to the magnet. But as you can see from the video, this just causes the magnet to rotate wildly out of control lol.

Is there a different component i should be using for this? So basically all i want is for the collected items to sway downwards when the magnet is rotated to the left or right. I’m using a combination of rotation through code and a hinge joint for the magnets rotation, and an anchor which it rotates around. It worked perfectly until I added hinges to the collected items.

I’m making a similar game to this, and basically want to emulate the effect these toys have when attached to the claw, except I want to make it a little better than this game…

Edit: My time stamp didn’t seem to work, at about 4:50 you can see what I’m talking about

Thanks.

From what I can tell there are multiple things potentially going wrong here and assuming your code is correct which you haven’t shown but it’s likely, parenting, the rigidbody settings themselves such as gravity etc. and layers. I suspect the biggest culprit though is probably if you have multiple colliders on the same layer all suddenly colliding with each other and that’s probably what is causing you the most issues.

You’ll need to experiment bit by bit to eliminate each possibility and get it working how you want. I don’t know how much you know about the pivot center but that will be affecting how your objects are snapping to your magnet.

I kinda fixed the issue, but it’s more of a bandaid fix? No colliders on my collected objects btw, they’re just visual objects. I locked the hinge joint on the magnet. The issue with this is, I want my magnet rotating as well, in the above video it’s actually rotating 100% through code(i thought the hinge joint was smoothing it out a bit, but no, it wasn’t lol).

The thing is the hinges, which are being spawned as children of the magnet, are causing the hinge joint on the magnet to rotate. I want the hinge on the magnet to rotate independently from the objects. The parenting goes like this, MagnetAnchor>Magnet>CollectedItem. Here’s my code for collecting an object, it’s kinda jank but…

    void CollectItem(GameObject item)
    {
        GameObject i = Pool.pool.GetObject(collectedObj);
        i.transform.parent = magnetAnchor.Find("Magnet");
        i.transform.localPosition = Vector3.down / 2;
        i.GetComponent<SpriteRenderer>().sprite = item.GetComponent<SpriteRenderer>().sprite;
        i.GetComponent<HingeJoint2D>().connectedBody = magnetAnchor.GetComponentInChildren<Rigidbody2D>();
      
        GameManager.gm.CollectItem(item.GetComponent<Item>());

        if (!movingUp)
        {
            movingUp = true;
            GameManager.gm.magnetMoveStarted = true;
        }
    }

How do you change the pivot center? It kinda looks nice now, but I’d rather not have my hinge on my magnet limited, I just want the collected objects to rotate on their own and the magnet to rotate in relation to the movement.

To change the pivot center in Unity what you do is create a separate empty and then parent your gameobject to that, the code that controls the rotation and so on must be made children of the new empty. A great example I’ve seen is with a door and the pivot center simply dictates how a gameobject rotates around it’s axis and so on so you can prevent a lot of weirdness that way.

As for the rest of the stuff, I’d say this is more down to how you’re using your hinge joint and the settings from the behaviour I’ve seen. If you want to have the magnet act like it’s on a hinge then you should create a separate empty and attach the hinge joint to that perhaps.

Really though this sort of thing is about experimenting, the setup of your hierarchy and your settings in this case has far more effect on things than the code unless you’re doing something weird but I don’t think you are. One thing I will say though is never use Find (“String”) it’s extremely wasteful, there are better ways to grab your objects like tags and so on.

Ah, the Magnet Anchor is my pivot center, I just had no idea that’s what it was referred to as haha.

Well, I’ll show a picture, so my hinge is set to the magnet anchor.But it doesn’t rotate around the pivot point, it seems to just rotate from it’s own center, like you can see in the previous video. Here’s my hinge settings for the magnet…

https://imgur.com/a/eR9mur7

Also, not sure why but the rigidbody was creating some weirdness, making it not move when the parent did, so I added the “position holder” script, it’s just a super basic script that gets the local position, and keeps the object on that local position. Maybe that’s why it’s not rotating properly?

Edit: Should’ve tried it out before posting, lol, no the position holder wasn’t the issue. Disabled it and it had the same issue.

With regards to any strange behaviour this is yet again is probably going to be down to your hinge joint settings. You’re going to have to experiment unfortunately and physics can be an annoying subject in game engines to deal with. I would recommend checking out specific tutorials and read the documentation on the joints themselves and it will probably give you some clues as to why you’re running into issues still. Having a look at your settings you posted, you probably should consider fiddling with things like the angle limits instead of leaving things at zero.

Rigidbodies and the various built-in physics joints that unity offers love to spaz out if they don’t have limits and they are moved around through code. Say for example if you move your rigidbody with a mouse with no gravity it might just keep infinitely moving in that direction unless you move the mouse again because it’s reading off the position co-ordinates that your mouse has moved and going off that instead of being limited in some fashion by the physics settings.

You need to understand all of this if you want to get the physics results that you’re aiming for and it can be a pain, depending on the situation it may even better to have the code mimic the result that you want so it’s not so unpredictable. For example you could make use of the new knowledge of what a pivot center is and have that rotate through code as if it’s swinging like a joint and that might be a better option for you. I can’t make these decisions for you though because only you know the effect you’re going for.

If it makes you feel any better, I’ve been at this awhile now and awhile and back when I was experimenting with trying to make a makeshift rope of sorts using a mix of spring joints etc. whenever I tried moving it with the mouse similar to how you’re wanting to do it the physics would break. So it’s not just you, physics in general can be very fussy which is one of the reasons I suspect a lot of game devs don’t really bother with any kind of complex physics mechanics that hasn’t been clearly laid out beforehand.

Yeah, Physics in Unity is such a pain to work with…

So, the thing is, I don’t really know how to go about making it sway with the hinge… As I mentioned, the rotation in the video was manual rotation. I was lerping the angle based on the horizontal velocity, but it doesn’t look very good, it’s not very smooth(could just be an issue with my code, I’m not great at rotations). So what I want to happen is, the magnets anchor, aka the pivot point, should sway to the left when I move to the right and vice versa. It doesn’t sway at all when the parent moves, until it has children, then it goes all outta whack lol.

https://imgur.com/a/wsicWSV

Right now I’m testing with a hinge on the magnets anchor, which is connected to the rope’s rigidbody. The rope is the parent of the magnet anchor, you can see on the left of the image in the hierarchy. Maybe a hinge joint isn’t even the right solution, i don’t know what is. This is my current code for rotation, though,

        velocityX = transform.position.x - prevXPos;
        prevXPos = transform.position.x;
       
        magnetRotGoal = velocityX * magnetRotStrength * Time.deltaTime;
        currentRotation = Mathf.MoveTowardsAngle(currentRotation, magnetRotGoal, magnetRotSpeed * Time.deltaTime);
        magnetAnchor.eulerAngles = new Vector3(0, 0, currentRotation);

PS, it’s moving with RB.MovePosition.