- Home /
Detecting When Intersection Penalty is Being Applied
So I'm making a game where the size of certain objects with rigidbodies is scalable. Unfortunately, there's nothing stopping me from upscaling them into a place where they won't fit. When that happens, Physics applies a penalty force to push them out of an intersection. I'd like to stop the scaling when that happens, but I've found no way to check it.
It seems like there should be a way to check if that penalty force has triggered in the last frame. Does anyone know how to access that or otherwise detect if two objects are intersecting (not just colliding)?
Answer by ferro · Apr 17, 2012 at 09:58 PM
If your collider is sphere or capsule there are methods to check intersection.
Physics.CheckCapsule
Physics.CheckSphere
methods does that.
Or, maybe you can make rigidbody of your objects kinematic and scale them up until OnCollisionEnter method is triggered.
Answer by Lttldude · Apr 17, 2012 at 10:19 PM
If I understand correctly, you just want the scaling to stop when it gets too big and like hits a wall or some collider/rigidbody, but still be able to go back down
I think you could use OnCollisionEnter or OnTriggerEnter. Basically, when it collides with something, save the current scale vector3 and enable the stopscaling portion of script in the update function, thus making it so the scale is locked at that maxScale vector3. When it exits (not colliding), it will disable the stopscaling script and allow scaling to resume.
Here is an example with OnCollisionEnter:
private var stopScale = false;
private var maxScale : Vector3;
function OnCollisionEnter(collision : Collision)
{
if(collision.gameObject.tag == "wall") //you don't need this conditional statement if you want it to stop scaling when it hits anything, this just allows you to be specific with what stops it's scale
{
maxScale = transform.lossyScale;
stopScale = true;
}
}
function OnCollisionExit(collision : Collision)
{
stopScale = false;
}
function Update()
{
if(stopScale)
{
transform.lossyScale.x = Mathf.Clamp(transform.lossyScale.x, 0, maxScale.x);
transform.lossyScale.y = Mathf.Clamp(transform.lossyScale.y, 0, maxScale.y);
transform.lossyScale.z = Mathf.Clamp(transform.lossyScale.z, 0, maxScale.z);
}
I haven't tested this script so there may be some bugs, but get back with me if it doesn't work. Good Luck.
Unfortunately, it isn't quite that simple. A lot of these objects are touching the ground or a single wall and I want that to still work. What I don't want to work is if an object is "pinched" between two non-rigidbody objects. When that happens, the penalty force gets applied from both sides and makes the object 8 different kinds of jittery.
I've managed to get some results from SweepTests in cardinal directions, but it isn't perfect and doesn't seem to work for mesh colliders or objects with multiple colliders. Also, SweepTests don't seem to work if the object is already touching something, just if it's about to. Also, it doesn't differentiate between objects with rigidbodies (which would get pushed out of the way) and objects without them.
There has to be something in Unity's physics system that detects when to trigger a penalty force. Unfortunately, the engine hides some things from developers and I'm worried this might be another thing like that.
Well you could check when it is in collision with two colliders/rigid bodies by using OnCollisionStay, which changes a boolean to true, and when tehy exit it goes back to false. Then in the update function if both booleans are true, then you stop the scale. $$anonymous$$ake sense? I apologize if it doens't.
Your answer
Follow this Question
Related Questions
Velocity data from OnCollisionEnter is delayed (incorrect) 3 Answers
OnCollisionEnter: collision.gameObject has weird behaviour 0 Answers
How to setup character Collisions? 2 Answers
Is it necessary to attach a rigidbody/colliders to child objects? 1 Answer
Excluding some physics collisions 3 Answers