In my game I have 2 objects. I want them to be able to collide and not go through each other. Currently Collision is working, but when one object pushes the other, he other starts floating away. I don't want that. How can I get collisions(not going through each other) without the physics(floating away, pushing, etc)?
The component that makes the gameobject react to external forces applied on it is the Rigidbody
-You can configure constraints on your rigidbody so the passive physics (forces coming outside the object, like gravity and collisions) won't work in the axis you block. Only active forces will (like AddForce() method)
Ridigbody Component in Editor with all constraints enabled
-In static objects (like walls, a tree) you can remove the rigidbody components. It will enhance performance too. Only use rigidbody in dynamic objects like characters, vehicles, balls, bullets
-Between A and B object, at least one of them must have rigidbody, or the collision detection won't be possible (in the object which contains the method OnCollisionEnter (or Stay)
But be careful. Without the rigidbody, you won't be able to use the AddForce() method to move object. If you use simply the Translate method on the Transform, the collision detection will become a such unaccurate
Related
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.
In Unity3D, you need rigidbodies on GameObjects that use colliders, as they use physics. You don't need rigidbodies on static GameObjects because they don't use physics, though you still need to have at least one in the calculation.
My situation is this: I want the game to detect putting your head through a wall with colliders. I'm just curious, as the collider on the head won't use physics, does it still need a rigidbody as it's moving, just not with physics?
My question is: Does a VR object need a rigidbody? (and yes it set it to kinematic)
Colliders → Collision action matrix
=> It depends.
Some of the combinations only cause one of the two objects to be affected by the collision, but the general rule is that physics will not be applied to an object that doesn’t have a Rigidbody component attached.
You said
as the collider on the head won't use physics
But note that in general Collision = Physics.
So yes, at least one of the objects involved in a collision needs to be a (kinematic) Rigidbody.
As you can see in the matrix above e.g. for a collision with a static object the event (like OnCollisionEnter) will be invoked only on the object with a (kinematic o not) Rigidbody but not on the static object.
static here means it has no Rigidbody component attached even if it is moved by code or in other words: As soon as something moves in your scene it should have a (kinematic) Rigidbody component!
You can add colliders to a GameObject without a Rigidbody component to create floors, walls and other motionless elements of a Scene. These are referred to as static colliders. At the opposite, colliders on a GameObject that has a Rigidbody are known as dynamic colliders.
Im trying to make a game in Unity and I want to have a gameObject fall and match the shape of the ground underneath it.
when the game is started:
what is does:
what I would like it to do
I'm pretty decent so even a hint in the right direction would be helpful.
thanks.
One way to do it is to duplicate the ground object and replace the falling object with ta modified version of that duplicate. How you can do that is to do the following on entering a collision between the falling object and a given ground object:
Make sure this falling object hasn't already collided with this ground object, such as with a fallingObject.lastCopiedGroundObject GameObject.
Find the y of groundObject's Collider.bounds.size
Add y to groundObject.transform.position to a new Vector3 newPos
Use GameObject newFalling = Object.Instantiate(groundObject, newPos, groundObject.rotation, fallingObject.parent).
Copy rotationalVelocity and velocity from the fallingObject's rigidbody over to newFalling's rigidbody, if appropriate.
Add, remove, modify components as necessary on newFalling, (such as replacing textures) to make it further behave and appear correctly as the falling object it is replacing.
Destroy the old falling object with fallingObject.Destroy()
Set the lastCopiedGroundObject of newFalling so that newFalling won't do this interaction with the same groundObject again, until another copy is done.
This will place the falling object above the ground object, and will let it fall using the physics engine to determine where it should rest on top.
One consideration is to instead use a List<GameObject> alreadyCopiedGroundObjects and to append the newly collided ground object to the list in the old falling object so that if the falling object touches multiple grounds, it will only change its shape to each one only once, so it won't perpetually oscillate between shapes in certain conditions.
I am making a simulation of some fish in a lake.
I am using rigid body as otherwise they move through the sides. But when they hit into the sides they rotate and then the script I have to set their rotation to 0,0,0 when they leave fails.
Your problem may be occurred by the fact that you are using unity's physics to move the fish but trying to set rotation directly. In this case movement and rotation of the fish are driven by Physics and forces, applied to the object. But you still can affect rotation and position if you reset all forces. Try looking here to learn how to remove forces.
Also when dealing with Physics in Unity, don't mess Update() and FixedUpdate() methods, because it may lead to an incorrect result.
When you say "hit into the sides" do you mean the sides of the simulated lake?
If so, one option might be to set the objects that denote the sides as "kinematic." Then you can detect when a GameObject (such as a fish) collides with it but it won't cause any physics reaction.
(ref: RigidBody)
I have a parent object, which has four children cubes. The parent has rigidbody, no collider. The four cubes only have colliders, which trigger tags are set true. I want to handle collision in the parent object. However, it didn't work. I know use onCollisionEnter may work, but I must use trigger. Could anybody give me some ideas?
Trigger colliders are unable to use OnColliderEnter because things pass through them instead of colliding. If you wish to detect when an object enters a trigger collider, use OnTriggerEnter instead.
https://docs.unity3d.com/ScriptReference/Collider.OnTriggerEnter.html
If however you wish to keep the trigger colliders and make them collide only with specific kind of objects, you can add a second set of colliders that are not triggers and use layers to differentiate which objects can collide with them and which ones pass through. You can then go to Edit->Project Settings->Physics and at the bottom at Layer Collision Matrix configure which layers can collide with each other.
https://docs.unity3d.com/Manual/LayerBasedCollision.html