0
\$\begingroup\$

I had some questions about Physics / Rigidbody in Unity.

  1. I have a 2D sprite with a collider. The 2D sprite is simply a card that I place on a table with the mouse. I use the collider for raycasting (so that OnMouseDown is called on the card). In this case, should I change the card’s position via the Transform or via a Rigidbody (which I don’t have right now)? I would say via a kinematic Rigidbody, because anything that has a collider and moves should be controlled through the Rigidbody for the colliders to work correctly (well, actually this is what I think, see question 2).

  2. Is it true that if I have a GameObject with a collider and the GameObject moves, then the GameObject must have a Rigidbody? (Moving the GameObject by changing the Transform is bad for the collider?) I came across this post (please read it) and the staff user answering the post seems pretty sure about this (or maybe I understood nothing...).

So, this is my code when using the transform to change the position of the card (this works perfectly):

 private void OnMouseDown() { _startPosition = transform.position; _startDragVector = FromMouseToWorld(); } private void OnMouseDrag() { Vector3 currentDragVector = FromMouseToWorld(); transform.position = (currentDragVector - _startDragVector) + _startPosition; } private Vector3 FromMouseToWorld() { Vector3 sp = Input.mousePosition; sp.z = 0; return _camera.ScreenToWorldPoint(sp); } 

Instead, this is my code when using the rigidbody to change the position of the card (this works perfectly, but slightly different due to the Lerp):

 private void FixedUpdate() { Vector2 mov = Vector2.Lerp(_rb.position, _currentDragVector, Mathf.Clamp01(Time.fixedDeltaTime * speed)); _rb.MovePosition(mov); } //OnMouseDrag is called every frame, so it isn't like FixedUpdate, i.e. it's like Update private void OnMouseDrag() { _currentDragVector = FromMouseToWorld(); } private Vector3 FromMouseToWorld() { Vector3 sp = Input.mousePosition; sp.z = 0; return _camera.ScreenToWorldPoint(sp); } 

Which is the right approach? Thanks in advance :)

\$\endgroup\$
3
  • \$\begingroup\$ If you are making a 2D card game, you do not ned any rigidbody. A rigidbody is basically telling the engine: I want physics affect this object. For a card game, this is usually not needed, they move to fixed positions compared they get thrown on the table and slide until they hit the game masters glas. \$\endgroup\$ Commented Oct 23 at 19:01
  • \$\begingroup\$ @Zibelas The main thing that puzzles me is this post: discussions.unity.com/t/… Where it seems that a rigidbody is always needed when moving a gameobject with a collider on it. \$\endgroup\$ Commented Oct 23 at 21:00
  • \$\begingroup\$ I would be surprised if you need a rigidbody just because there's a collider. \$\endgroup\$ Commented Oct 24 at 13:44

2 Answers 2

1
\$\begingroup\$

The advice you've found is a little oversimplified. There's an unstated assumption here:

If you have a moving object with a Collider2D and you want that movement to interact with other physics objects, then it should have a Rigidbody2D.

Very often that bolded part is implicit in the context. If someone is asking about moving a character in a platformer, or a vehicle in a driving / spaceflight game, then they almost certainly want the Collider2D to...

  • Stop the object from moving into / through solid obstacles.

  • Fire trigger & collision events when it hits enemies / hazards / power-ups.

  • Push other movable objects around.

These things can fail to happen, or happen in glitchy, inconsistent ways when you don't have a rigid body.

And so, you'll see a lot of advice that jumps directly to "always use a rigid body to move" because that's almost always the right answer, and they don't always clarify that it's based on these assumptions.

Your case isn't that though - you only need the collider for mouse picking / raycasting, and don't want any physics interactions with the other physics objects. So, your situation is the rare exception to the rule, where it's actually safe to skip the Rigidbody2D for this purpose.

Performance

Moving a Collider2D isn't free. Each time you change the transform, the engine needs to clone those changes into the Box2D simulation so that your raycasts and mouse picks work correctly.

In my tests, that sync-up adds something like .1-.2 ms to the frame time, but not per object. Most of the cost is doing the sync at all, and the per-object cost is much lower, so having a bunch of moving colliders doesn't compound the cost too badly.

In older versions of Unity, moving a collider without a rigid body was much more expensive, and so you'll see a lot of superstition and misinformation about it lingering around the net, saying that skipping the body will tank your performance. (I was guilty of this myself, until a user here pointed out to me that this issue was patched years ago).

The best way to see how the performance compares for your situation/version is to use the built-in profiler to measure it.

When I do that in a recent Unity 6 version, I find adding a Rigidbody2D to a moving Collider2D is still significantly more expensive when it's moving near other colliders than when I do the same test with no body. So you don't gain performance this way - at least not on desktop. To be sure, verify this on your own target platforms with a scene representative of your in-game use case.

To minimize any spurious collision-handling work in these tests, I had "Is Trigger" checked on all my colliders, and I put them all in a "No Collide" physics layer with its interactions disabled with all layers (including itself):

No-Collide layer collision matrix configuration in Project Settings > Physics 2D

\$\endgroup\$
3
\$\begingroup\$

The key difference is: do you want physics to interact with your object or not. And if you need it or not will depend on your game.

Updating the position directly will place the object there, regardless if there is something or not. Since you mentioned a card, it is easier to NOT use a rigidbody. You would want physics interaction in case when you push your card across the table, it should push other cards away. But in a card game you have fixed positions where cards should/ can go and it would look weird if other cards get affected in there position just because you touched them while moving your own card.

Your second piece of code would also workd with the position directly and still using lerp by just giving the start position (probably from your hand) to the destination position (table, trash, etc).

If you are creating a game similar to table top simulator, your card would probably have a rigidbody. But in 97% of all other card games, it wont be needed and you can move your card by position directly.

I have made a few mini card games that have neither collider nor a rigidbody. They mainly use the canvas and are just images. I use a placeholder image at the drop location to indicate where the card/ tile will go when placed down and snap it afterwards to that position.

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ In your example game you used the UI canvas, therefore in that case you don't have to attach a collider on the cards so to be clickable and draggable. Sadly, in my case the cards are not in the UI canvas, so they must have a collider in order to be clicked and dragged. And according to this post, every movable having a collider must be moved through a rigidbody: discussions.unity.com/t/…. Note: actually mine is not a card game, that was a semplification. Anyway, I need to drag things on the scene (no need to collide). \$\endgroup\$ Commented Oct 24 at 7:32
  • 1
    \$\begingroup\$ You need to use the rigidbody in combination with moving ONLY if you want to have physics interactions during the move. If you do not care about that, there is no need to use the rb for moving \$\endgroup\$ Commented Oct 24 at 14:26

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.