Problem:
red box never collides with blue capsule.
What have i done:
-checked collision layer matrix(everything is enabled)
-both objects have colliders and capsule has rigibody(static)
-sorting layer(box is above capsule)
-tried using istouchingLayers and OnCollisionEnter2D(both don’t work)
-layers and tags are setup corectlly
With Physics (or Physics2D), never manipulate the Transform directly. If you manipulate the Transform directly, you are bypassing the physics system and you can reasonably expect glitching and missed collisions and other physics mayhem.
Always use the .MovePosition() and .MoveRotation() methods on the Rigidbody (or Rigidbody2D) instance in order to move or rotate things. Doing this keeps the physics system informed about what is going on.
The only way you can correctly move physics objects is to use the Rigidbody2D API. Plenty of tutorials on that. You’re bypassing this and just setting the Transform which is wrong. You’re just causing your red collider to be recreated at that new position.
When you don’t add a Rigidbody2D then the collider is implicitly Static (non-moving).
Static bodies don’t collide with Static bodies.
Your Red collider object should have a Rigidbody2D which you use to move it and it should be set to be Dynamic. Dynamic does contact Static but note, the blue one won’t move, it’s Static.
Explicitly positioning (MovePosition/MoveRotation) is normally used for Kinematic stuff, not Dynamic Rigidbody2D. There’s the ability to set velocity directly or add forces for Dynamic bodies.
There’s plenty of tutorials online about this on Unity Learn or YouTube. A forum isn’t the place to start teaching how to do it TBH.
NOTE: As I said, don’t be so fixated on the Transform. Don’t read it as the authority of position, use the Rigidbody2D API to find that. This is no longer a renderer, it’s physics, you need to use the API provided.
This says “move heaven and earth and track physics as you SLAM the enemy to the player’s current position,” so of course it happens instantly.
You can use methods like MoveTowards() and give it a small amount to move each frame, usually a construct like this:
Vector3 position = enemyRigidbody.position;
position = Vector3.MoveTowards(
position,
player.transform.position,
// this 5.0f is "Enemy Speed"... use a variable for it!
5.0f * Time.deltaTime);
enemyRigidbody.MovePosition(position);
Or if you need navigation around obstacles, look up any of the ten billion or more youtube videos already out there for this stuff.
My goal is to make red box(enemy) move towards capsule(player), it works with Your solution and also mine which i mentioned before, but for me red box doesn’t move smoothly towards capsule or my eyes are just misleading me.
//Havent tested this, let me know if my maths or code are wrong
Vector2 dirToPlayer = (player.position - transform.position).normalized; //Direction from Vector A to Vector B is B - A normalized (I think, change the values if it doesnt work)
rb.velocity = dirToPlayer * 5.0f //5.0f should be your speed variable.
Incorrect. It moves the body through space to the position specified and detects all the collisions on the way.
For 2D it works this way for both Kinematic and Dynamic bodies. In 3D it works this way for Kinematic bodies but for Dynamic ones it does indeed teleport i.e. move it instantly to that position.
Also note that “MovePosition” doesn’t work there and then, it does nothing there and then. It works when the simulation runs. You might issue lots of these per-frame but only the last one you did before the simulation runs will do anything. This is why it’s typically called in the “FixedUpdate” callback that happens prior to the simulation step running.
Unless of course you’re running physics per-frame, in which case you don’t need to use this and you can simply set the velocity or just set Rigidbody2D.position and interpolation is automatically turned off.
If I had a dynamic rigidbody2d object with a collider, and I was trying to teleport (instantaneously move to a specified location), and I was trying to ignore all collisions in-between its current location and that teleport point, what would be the recommended solution.
In 3D it’s as simple as you describe. But in 2d I would have to turn on and off the collider? Would I have to turn it off this frame, and then in the future turn it back on?
Which then requires me to do an addition getComponent to find the collider2d. But then I would have to turn it back on.
If I have an onTriggerEnter event to teleport. what’s the cleaniest way to turn it back on next frame. Would it be an Invoke? Seems a bit hacky. But maybe I am just not aware of the easy proper solution
If you instantly move it to a new position, what makes you think it somehow detects all collisions inbetween those two positions; it doesn’t. That’s what the term “teleport” means, it’s just in a new position.
No idea where you get this idea from.
If you want to instantly move a Rigidbody2D to a new position then you set Rigidbody2D.position to something.
In 3D it incorrectly uses MovePosition, it’s not easy in 3D. In 3D a Dynamic body using MovePosition is the same as Rigidbody.position being set.
I was literally quoting you, MovePosition find all collisions in-between two points. While position does not, that was the clarification I needed. Thank you.
Yes, that’s MovePosition but you were asking about “teleporting” which isn’t MovePosition, it’s the opposite of teleporting hence me not following you at all.
Seems I clarified something for you though so I guess that’s good.