- Home /
Make rigidbody slower not stop after hit kinematic rigidbody
I placed props on my map and they are kinematic and they have script that if car will hit them than kinematic is false. But car on hit stops. How to make only slow down? You know, when car with 999 km/h will hit trash can, car can't stop.
Rather than setting them as kinematic, would it be reasonable to put them to sleep when the scene starts ins$$anonymous$$d?
On instantiate objects falls even with sleep() on start/awake. And there would be problem when something will hit prop and I don't want to it fall, like when player will touch lamp.
Well, in a variety of tests, although I could reliably get a Rigidbody to sleep upon start, I couldn't get it to reliably go back to sleep upon impact. So ins$$anonymous$$d, it looks like the main consideration should just be to try re-adding the collision force to the car. Posting my take on it as an answer.
keep track of the cars speed (velocity) and when it collides with the can reapply a reduced amount of it then.
just like hexagonius said. Put the velocity when the car hits something into a vector3, and then apply a reduced version of this velocity.
if(*car collides*){
new Vector3 VelocityWhenHit = car.velocity;
car.Velocity = VelocityWhenHit / 5;
}
It not work well, car still stops on hit, it works when car rubs against the object. if I set velocity after time, there will be a short jerk.
Answer by Eno-Khaon · May 07, 2018 at 11:36 PM
One approach you can try taking to handle this is to essentially do what you've been doing, treating the objects as kinematic until hit. When the collision occurs, you can determine whether the hit should make an object "break free" (A light pole, for example, would be tough to break through, while a trash can would be trivial).
If it doesn't, you don't need to take any action. The stationary object won.
If it does "break free" then re-apply the collision force to the incoming object (car).
My example script in full:
// C#
using UnityEngine;
[RequireComponent(typeof(Rigidbody))]
public class MovableObject : MonoBehaviour
{
public float breakingForce = 10.0f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
rb.isKinematic = true;
}
private void OnCollisionEnter(Collision collision)
{
Rigidbody other = collision.rigidbody;
if(other != null)
{
float collisionForce = Vector3.Dot(collision.relativeVelocity, collision.contacts[0].normal) * other.mass;
if(collisionForce > breakingForce)
{
rb.isKinematic = false;
other.velocity = collision.relativeVelocity;
}
}
}
}
Essentially, the idea is to still let the physics handle a majority of the work, while trying to keep things under control. By extension, this also ensures that an object affixed to the ground won't spontaneously try to move upon colliding with the ground itself, by requiring enough force to enable it to move and taking mass into account for all other physics-based portions of the process.
A car generally weighs a lot, for example, so it would need less speed when impacting a resistant object to break it free. A baseball thrown at 100mph, by contrast, could be moving faster, but wouldn't provide as much force, even when compared with a glancing hit from the car.
relativeVelocity was the key, thank you and I forgot about the mass, thanks for the hint and example
Your answer
Follow this Question
Related Questions
Detecting When all rigidBodies have stopped moving 2 Answers
Rigidbody.velocity.magnitude only returns value of the Y axis 1 Answer
How to apply relative force to Ball using another object? 0 Answers
Rigidbody magnitude comparison is not working correctlly? 2 Answers
Modify rotation based on passing rigidbody's velocity and direction? 1 Answer