- Home /
How to clamp gameobject movement in a irregular shape
Hello,
I am using a runtime gizmo to translate gameobjects in my game. I need to know how to clamp the objects movement in an irregular shape.
For example: If the shape is a Box.
I can calculate the Bounds of this shape and using the Bounds.max.x, Bounds.min.x, Bounds.max.y, Bounds.min.y, Bounds.max.z, Bounds.min.z and clamp the position like this:
Vector3 pos = gameObject.transform.position;
pos.x = Mathf.Clamp(pos.x,Bounds.min.x,Bounds.max.x);
pos.y = Mathf.Clamp(pos.y,Bounds.min.y,Bounds.max.y);
pos.x = Mathf.Clamp(pos.z,Bounds.min.z,Bounds.max.z);
gameObject.transform.position = pos;
This is all good till it's a box or a rectangular shape, because I can use either Renderer.Bounds or Collider.Bounds, However, if it is a irregular shape like this:
And, I calculate Bounds value, it will be incorrect since Bounding box/bounds will always be calculated in a square/box shape and will give incorrect max and min value, making the gameObject go outside the shape.
I am using the below RuntimeGizmo to translate my gameObject. https://github.com/HiddenMonk/Unity3DRuntimeTransformGizmo
p.s. The Shape in my case is a square shape and a L-shape room, made by using primitive cubes acting as walls. gameObject in question is a piece of furniture.
Do you have an solution for this problem? I have the same problem now
Answer by BastianUrbach · Oct 12, 2018 at 04:00 PM
First of all, you can do it for all convex colliders (all primitive colliders as well as mesh colliders marked as convex) like this:
transform.position = someCollider.ClosestPoint(transform.position);Unfortunately that doesn't allow for an L-shape because that would be concave. However, you can build concave shapes from several convex shapes (for example an L-shape from two boxes). Then you just need to select the one that gives you the closest point:
public Collider[] shapes; void Update () { Vector3 bestPoint = transform.position; float bestDistance = float.MaxValue; foreach (var c in shapes) { Vector3 currentPoint = c.ClosestPoint(transform.position); float currentDistance = Vector3.Distance(currentPoint, transform.position); if (currentDistance < bestDistance) { bestDistance = currentDistance; bestPoint = currentPoint; } } transform.position = bestPoint; }