How to add reaction force to a collision in Unity? - unity3d

So when using rigidbody physics on a 2d sphere and a spinning animated 2d rectangle it only pushes the sphere aside when it collides. What I'm wanting is the sphere to fly off when collided (don't ask if it's if it's a problem with it colliding or not).
I've tried the physics materials and adjusting the rigidbody and such but nothing works. There's not a single thing online about it so attempting to code physics would be very difficult.

If I understand correctly.
You could apply AddForce or AddForceAtPosition function with ForceMode.Impulse argument to sphere when Collider2D.OnCollisionEnter2D(Collision2D) event trigger.
Or Just modify sphere speed when Collider2D.OnCollisionEnter2D(Collision2D) event trigger.
Note that Collision2D have contacts and relativeVelocity which may help you calc the force vector.

Related

How do I check for and resolve collisions within FixedUpdate using a kinematic rigidbody?

I have been working on my own kinematic character controller for a while, but only recently learned that one should consider updating its position and rotation using Rigidbody.MovePosition and Rigidbody.MoveRotation instead of directly modifying the Transform component, which is what I am doing now. While my controller works fine, and does not cause any noticeable performance impact in my small games, I want to better understand the benefits of manipulating the Rigidbody component, and especially how this all works within FixedUpdate instead of Update.
To be clear about the supposed impacts on performance, Unity's manual on 2D rigidbodies says:
Any Collider 2D component added to the same GameObject or child GameObject is implicitly attached to that Rigidbody 2D. When a Collider 2D is attached to the Rigidbody 2D, it moves with it. A Collider 2D should never be moved directly using the Transform or any collider offset; the Rigidbody 2D should be moved instead. This offers the best performance and ensures correct collision detection.
Right now, my basic controller loop looks like this in the Update method:
Read the user's input velocity
Modify the controller's velocity based on this input (this velocity is distinct from Rigidbody.velocity)
Using Physics queries, sweep the controller's body against the appropriate collision layers by velocity * Time.deltaTime
Pick a collision resolution position based on a set of rules
Set the controller's Transform.position to this resolution position
I also have a method that moves the controller using Transform.Translate if no collision detection is needed.
As you can see, though my controller GameObject has a kinematic rigidbody attached to it, I never actually use it for anything. Unity's documentation on kinematic rigidbodies is conflicting, stating here:
Note: MovePosition is intended for use with kinematic rigidbodies.
but also here:
If isKinematic is enabled...The rigidbody will be under full control of animation or script control by changing transform.position
I am also unsure about how to manually check for collisions within FixedUpdate, as I have read that FixedUpdate can be called more than once per frame. Frankly, I thought FixedUpdate was only supposed to be used with dynamic rigidbodies to simulate real physics, and thus have only used this method for simple manipulation of those kinds of rigidbodies.
And then Rigidbody.MovePosition states that
2D rigidbodies have a fixed limit on how fast they can move therefore attempting to move large distances over short time-scales can result in the rigidbody not reaching the specified position during the next physics update. It is recommended that you use this for relatively small distance movements only.
What if my character needs to move a very large amount? Do I just set Rigidbody.position directly?
I guess I am trying to figure out how I can reconcile all of this logic to conform to what Unity says is best for performance. Perhaps I need to combine Update and FixedUpdate, but ultimately I am just hoping to receive some clarification and guidance regarding all of this.

[Solved - 3D movement on X and Y with mesh colliders

I am working on an Asteroids clone in 3D with top-down camera. This setup is static and will not change (so no, I do not want to transform the project to 2D game instead).
This means that I need to limit all movement to X and Y axis. I created movement for both asteroids and player and everything worked fine. All movements are done using AddForce on respective RigidBody components.
The problem is then I start dealing with collisions. I use Mesh Collider components to get a nice and precise "touch reaction". The problem is that when collision like this occurs, the new movement vector has Z value different from 0. This is a problem as the object will start moving on Z axis.
What have I tried:
Freezing constraints on RigidBody
Manully reseting Z in Update function
The first solution (freezing constraints) did not work and neither did the second one (moreover, the second one seems quite messy)
So the question is
What would be the optimal way to force physics-based movement only to X and Y axis while using precise collision with Mesh Colliders?
are you sure you used the position restriction correctly? You can check to set the restrictions with a vector as in the documentation. https://docs.unity3d.com/ScriptReference/RigidbodyConstraints.FreezePosition.html
to see how its done. If not please share the code or a screenshot of the rigidbody restrictions you tried in the editor

Unity3D Collider Passing Through Other Colliders

The Problem: Mesh colliders on some rigidbody objects are passing through colliders on other objects.
Things I have tried:
With the assumption A is a GameObject with a RigidBody attached and B is a normal GameObject with a collider.
Give A a convex mesh collider
Give A a non-convex mesh collider
Give B a convex mesh collider
Give B a non-convex mesh collider
give B a box collider
give B a convex mesh and box collider
give B a non-convex mesh and box collider
Adjusting the weight of the rigidbody
I have tried all of these in all combinations of A and B.
In addition,
Colliders are not marked as triggers
All objects are on the default layer (0)
Checking isKinematic; doing this seemed to make gravity stop affecting the object, so I have left it as false.
Constraints: I want A to use a mesh collider since most of the objects involved are moderately complex, and fitting other colliders to them would take a while.
Weird Behaviour: I have some objects with both rigidbody and convex mesh collider where the collision is working fine with a non-convex mesh collider. This is inconsistent with other gameobjects. The objects have all of the same settings.
I am using unity version 2019.3.11f1 if that is relevant.
The object being used are from this package. Specifically, the filing cabinet with rigidbodies on the drawers works fine. The desk, office chair, pen, and open laptop all fall through the "floor" (a cube with all of the above colliders tested on it).
Do you have 'isKinematic' checked on the objects with rigidbodies that are going through other colliders? If so uncheck it so that external forces affect it.
edit you also need to click convex on the mesh colliders if they are colliding with other mesh colliders, Convex Mesh Colliders are limited to 255 triangles, are the objects that are not passing through have more than 255 triangles in geometry?
I am Assuming you have set your Collision Detection to Discrete In your gameObject's RigidBody, if so, please make sure to select Collision Detection to Continuous In your gameObject's RigidBody.
Reason Why this is not working
You are trying to use collision that has (speed > your Computer's frame speed) so, the frame is not catching the collider properly some time catches and some time fails to catch.
You are moving your GameObjects with tranform.translate or position etc. If so then make sure to use Rigidbody Related function for Positioning, rotating.
Solution Image For First Problem
I'm assuming
-you game object which contain the mesh component is very small ( bellow 0.7 size(x,y,z) so the game engine is little difficult to detect it)
and also
for the colliding objects at-least one rigid-body component must be attach to one object
This seems to be a common big problem, and I have been struggling with the same issue for days, and have finally fixed it, so am feeling like I should highlight one important thing:
move Rigidbody via MovePosition, not via just changing its position field directly, nor via changing position of GameObject holding it.
Changing position via "wrong" ways will "teleport" your rigidbody, physics won't fully work on it in that case.

Unity - handle OnCollision on child's Rigidbody

I have a GameObject, constructed from bunch of pills, where each pill is basically constructed from two spheres and a cylinder.
So the GameObject hierarchy looks something like this:
Player (Empty GameObject)
Pill (Empty Game Object)
Sphere (3D sphere)
Cylinder (3D cylinder)
Sphere (3D sphere)
Hopefully the picture will give you guys the visual illustration of what the GameObject looks like:
Now, my goal is to have the entire GameObject - Player as a Rigidbody, while I would like to detect collision on Pill level. Hence I added Rigidbody to Player and Capsule collider to each Pill. However such configuration does not work - the Pill does not receive OnCollisionEnter event. I found suggestion solution, however it does not work for me either - if I set Capsule collider property Is Trigger, then Player does not interact with other Rigid bodies. The only solution I found so far is to add Rigidbody to each Pill, but I am concerned about performance is such scenario.
To sum up - my question is - can I have the above configuration - parent rigid body, child collider work and accept OnCollision events? Of course if I can have parent rigid body and a child with Is Trigger set will also work in case the Player keeps rigid body physics behavior.
I don't know why you want to detect collision on Pill Level but retaining the same configuration one thing you can access is the Collision ContactPoint.

Small, "bouncy" lags when pushing an SKShapeNode with another shape moved by an SKAction

I am creating a 2D autoscroller and when my player (with a circle physicsBody) collides with an SKAction moveTo-powered obstacle which is moving towards it, it makes small, almost unnoticable lags. I tried lowering the friction and the density of the objects, but nothing helped. Any ideas?
You have chosen to use a circle with phycsicsBody. An SKPhysicsBody object is used to add physics simulation to a node. When a scene processes a new frame, it performs physics calculations on physics bodies attached to nodes in the scene. These calculations include gravity, friction, and collisions with other bodies. After the scene completes these calculations, it updates the positions and orientations of the node objects.
You have also chosen to use SKActions, when using the actions to move a body such changes don't go through the physics engine, indeed usually you could add unwanted actions and unexpected events as "bouncy lags".
So, if you're using physics to move a body, you shouldn't use move actions, apply an impulse or force, or set it's velocity directly
Setting restitution to zero may help. This controls the elasticity, or bounciness of a sprite.