- Home /
How to get the correct ratio of collision distance to total scale?
So am trying to squeeze something based on collisions. Making the object´s width the distance between collisions, basically. However, this has a problem: the object assumes that the collisions are always at max width. The object has been properly squeezed, but if the collisions are below:
The object assumes that the x scale should be that distance. So I thought getting the ratio of collision distance to total scaleX would work, like (originalScale.x / originalDistanceCollisions) distanceCollisions = (12 / 6) 3 = 6. In other words, if that distance is the half of the total scale, the scale will always be the double of that. However, this only works if the collisions follow the original collision contacts on the mesh. In this case, the points whose distance gave me 6. I can´t put another image, but if the colliders move from thpse points, they go through the object or they "pressed" it when there are no collisions.
I think you ought to rethink why you're doing this but I will help.
Look up what a ratio is and give some thought as to how you might use that in your project. I can help with the code however it is essential that you be able to figure things out yourself if you're going to making things.
I'll give you a hint about the code: "transform.localScale = new vector3(x,y,z);"
That's your code you just need to find out how to give your dimensions a ratio.
Thanks, but I need more help. I understand you are trying to make me less dependant of unity answers, but seriously, am more concerned with getting an answer. I also tried this, which is like you say: (originalScale.x / originalDiffX) multiplied by diffX; So, for example, (12/6) * 3 = 6; 6 is the original distance between collisions, which is the half of the object´s width. Therefore, if the collisions stay there, the localScale will always be the double of the diffX. That´s the problem: "if they stay there". If the collisions change placement it won´t be right anymore. Do you know how to solve this?
Ok. You misunderstand the math involved here I think. When you divide by a value and then multiply it by said value you cancel out their effects. It is the same as multiplying by 1/1 ! Pull up your calculator and type in 6 and divide it by 6.
If you lack the basic algebra skills to figure this out I suggest you rethink your approach.
Telling me you understand that I want you to think about it more carefully but then go on to say in the very next sentence that you "need it to work" but lack the basic math skills any high schooler could do, is insulting.
Excuse me, but I never divided something by 6 and then multiplied it by it again. I think you are confusing the variables "originalDiffX" and "diffX", which are not the same. originalDiffX is the original distance, while diffX is the updated one. It is true that in the frame of collision they will be the same value, and therefore they will cancel their effects, which is supposed to happen. $$anonymous$$eep in $$anonymous$$d that in that frame the object is still not being squeezed, so it has to keep its originalscale; but in the next frames diffX will change and it will be recalculated. Besides that, you didn´t had to be so rude.
$$anonymous$$y apologies, friend. I've not been feeling well.
I think it would be beneficial to know what you're ai$$anonymous$$g to achieve here before we go on looking for a solution though.
If you could explain in depth that would be great.
Answer by Hirnwirbel · Nov 23, 2018 at 11:23 AM
Hm. Maybe instead of checking for collision between the squeezers and the squeezed mesh, you could raycast from two points behind the squeezers towards the mesh you want to squeeze. The distance between the raycast hits is A (the width of your mesh at that height), the distance between the fronts of your squeeze objects is B.
Scale x must always be B/A, unless of course that number is greater than 1.
Edit: It just occurred to me, if you're raycasting towards the same mesh you're also applying the scaling to, the scaling might jitter back and forth between 1 and your desired squeeze scale. You could raycast towards an invisible "collision mesh" and apply the scale to a visible "display mesh" instead. Or maybe multiply your current scale by your squeeze factor every Update instead of setting it directly to the value.
Thanks for your detailed answer. You know, I was using raycast before doing this, but not like you. It was more like this : currentX = (this.transform.localScale.x * filter.mesh.bounds.size.x + extraLeft + extraRight) / filter.mesh.bounds.size.x;
Which is basically getting the updated x scale and adding or subtracting the extra values. These values are floats that change depending on raycast length, (both) like this: hit.distance - skinWidth;
skinWidth is also a float, like an extra space I was using to avoid putting the ray origin on the edge. That origin is defined as this = coll.contacts[i].point - Vector3.right multiplied by skinWidth; (or + ins$$anonymous$$d of - depending of the side). So originally I did this to increase the size when the squeezers started to separate, but then I realized that it also works for decreasing size (since when the hit.distance < skinWidth the extra values become negative).
Its similar to your solution because the squeezers need to go through the object it order to squeeze it. $$anonymous$$aybe you can help me with what I missed, because if those objects were moving fast it was visually obvious that they were going through and the correct scale was calculated after that. Anyway, that was not the reason I didn´t like raycasting. You see, if all objects in scene will be squeezed, their sizes will decrease and therefore the hit points will be wrong. The ray only hits a normal if it´s in front of it. Because some objects´ walls have some degree of thickness, they have normals from both sides. The skinWidth I was using worked at start, because it was smaller than that thickness, but wasn´t later; besides that, for some reason rays have issues with edges. So I gave up with raycasting. I imagine that this will be the case with any raycast solution. Do you have any other ideas? I think I have done everything I thought until now. If you don´t know, at least tell me that you have seen this.
Hey there
$$anonymous$$aybe you can help me with what I missed, because if those objects were moving fast it was visually obvious that they were going through and the correct scale was calculated after that.
How odd. If the colliders get their new positions and the object also uses those positions to get its scale in the same Update(), shouldn't it be happening in the same frame? $$anonymous$$aybe if the colliders get moved around with Physics, you need to use FixedUpdate() so it stays in sync.
You see, if all objects in scene will be squeezed, their sizes will decrease and therefore the hit points will be wrong.
Yeah, that's kinda what I meant with my edit above. Raycasting against the same mesh that gets scaled might be more difficult and error-prone than raycasting against an invisible "calculation mesh" that always stays the same size and applying the results to a collider-less "display mesh".
But I don't have any other idea right now... $$anonymous$$aybe if you give some more details on what exactly your scenario and goal is ( since you said something about fast moving colliders and that the entire scene gets squeezed ), someone can come up with an entirely different approach to the problem?
Yeah, I thought making the rays ignore certain layers in order to prevent the wrong hit points. One ray should only hit with the squeezer, and the other only with the main object. I haven´t tested it, but I think that it may work without having to duplicate each mesh. Also am using spherecast to prevent the missed collisions on the edges I mentioned, which I didn´t even knew existed until yesterday.
The colliders aren´t moving with physics. I was moving them in the scene view for testing, but they will move accordingly to the stage´s floor. $$anonymous$$aybe you can help me with that. Since I want an instant change in position am setting it directly, but it causes a lot of jittering. How can I lerp it if the change should be instant? I think that that was the main reason the objects were going through. It also happened more that way. When I was moving them in the scene view it almost didn´t happen. However, if they were moving fast they could accidentally go through too much and not squeezing it. Besides that, could this issue be related with framerate? I think, if my eyes aren´t lying to me, that it didn´t even happen when the framerate was smooth.
Your answer
Follow this Question
Related Questions
OnTriggerEnter and transform.localScale with Time.deltaTime problem 2 Answers
Detecting When Intersection Penalty is Being Applied 2 Answers
Sprite doesn't flip correctly. 1 Answer
How to simplify the equation of a moving vertex if its object is squeezed? 0 Answers
newbe scaling maze sceen for different resolutions 0 Answers