## Collision detection: How to properly tighten an object when pressed between two others?

@jgallant, @Hamza Hasan, I'm trying to do this: How can I "squeeze" an object from the game when pressed between two others?

What they both answered there, but with some problems, such as not returning to the original scale or not changing the size correctly based on the percentage of collisions (with what I am struggling). This is how I have solved it until now:

``````Original Vector3 Original scale;
privateX floating current;
private floating currentZ;
private float area;
public floating value minValue = 0.6f;
// 1 is perfect horizontal / vertical
Filter mesh filter;

public float skinWidth = 0.1f;
public float firstLenght = 0.2f;
// must be greater than skniWidth;

RaycastHit hit;

GameObject leftEmpty;
GameObject rightEmpty;

bool pressLeft = false;
bool pressRight = false;

float diffX;
original floatDiffX;

bool orig = false;

Empty Awake ()
{
filter = this.GetComponent();
}

void Home ()
{
originalScale = new Vector3 (filter.mesh.bounds.size.x, filter.mesh.bounds.size.y, filter.mesh.bounds.size.z);
area = originalScale.x * originalScale.z;
leftEmpty = new GameObject ();
rightEmpty = new GameObject ();
}

void OnCollisionStay (collision)
{
if (coll.gameObject.tag! = "Ground" && coll.gameObject.tag! = "Ceiling")
{
// if the collision is on the left side
for (int i = 0; i < coll.contacts.Length; i++)
{
if (coll.contacts[i].normal.x > minValue) // I'm checking the address according to the normals, not the positions
{
Vector3 rayOrigin = coll.contacts[i].point + Vector3.right * skinWidth;
if (pressed Left == false)
{
if (Physics.Raycast (rayOrigin, -Vector3.right, out hit, firstLenght))
{
Debug.DrawRay (rayOrigin, -Vector3.right * firstLenght, Color.blue, 0.1f);
// I'm doing all this to take the points of contact only when they're right (before they hit, they're wrong). So the point of contact is in the right place only if ...
if (hit.distance <= skinWidth + 0.00008f) // the last number is to compensate for the strange physics, just ignore it
{
leftEmpty.transform.position = hit.point;
pressLeft = true; // so the leftEmpty's position is set only once, then it moves through the parenting under
}
}
}

leftEmpty.transform.SetParent (coll.transform); // I am raising them to be able to keep them after OnCollisionExit because I will use these numbers also to return to the original scale
}
}
// if the collision is on the right side
for (int i = 0; i <coll.contacts.Length; i ++)
{
yes (col. contacts)[i].normal.x <- (minValue))
{
Vector3 rayOrigin = coll.contacts[i].point - Vector3.right * skinWidth;
yes (pressed right == false)
{
if (Physics.Raycast (rayOrigin, Vector3.right, out hit, firstLenght))
{
if (hit.distance <= skinWidth + 0.00008f)
{
rightEmpty.transform.position = hit.point;
pressRight = true;
}
}
}

rightEmpty.transform.SetParent (coll.transform);
}
}
}

if (pressLeft == true && pressRight == true && orig == false)
{
originalDiffX = Mathf.Abs (rightEmpty.transform.position.x - leftEmpty.transform.position.x);
orig = true;
}
}

Null update ()
{
diffX = Mathf.Abs (rightEmpty.transform.position.x - leftEmpty.transform.position.x);
// originally, I was doing this:
currentX = diffX;
currentZ = area / currentX;
if (leftEmpty.transform.position.x! = 0 && rightEmpty.transform.position.x! = 0)
{
if (currentX <= originalScale.x)
{
transform.localScale = new Vector3 (currentX / filter.mesh.bounds.size.x, transform.localScale.y, currentZ / filter.mesh.bounds.size.z);
}
}

// And it worked, but only if the collisions were always in the most separated points of the mesh (because the scale x was always the distance between collisions)
// That's why I wanted a percentage, on a scale based on the points of impact and not on the full width, so I did this:
currentX = originalScale.x / (originalDiffX / diffX); // o (originalScale.x / originalDiffX) * diffX; anything works.
// However, while solving the percentage problem, it only does so if the collisions remain at the original collision points, which will not be the case.
// then I tried this to get the original DiffX original of the updated diffX:
Vector3 closestLeft = this.GetComponent() .ClosestPoint (leftEmpty.transform.position);
Vector3 closestRight = this.GetComponent() .ClosestPoint (rightEmpty.transform.position);

float distX = Mathf.Abs (closestRight.x - closestLeft.x);
float mult = (originalDiffX / diffX) * distX;

currentX = originalScale.x / (mult / diffX); // the same formula but replacing the originalDiffX with "mult". I did not work at all. The object began to vibrate strangely.
}
``````