Home > database >  Find four points around a GameObject
Find four points around a GameObject

Time:02-03

I'm trying to wrap my head around what appears to be quite a simple problem.

I want to get four points around a game object. The object may be made up of multiple child primitives such as cylinders and boxes. I should point out that the parent object does not have a renderer. Here's an illustration:

enter image description here

I am able to get the four points by iterating the children's renderers, and encapsulating their bounds like so.

    private Bounds GetBounds()
    {
        var renderers = GetComponentsInChildren<Renderer>();
        Bounds bounds = renderers[0].bounds;

        for (int i = 1; i < renderers.Length; i  )
            bounds.Encapsulate(renderers[i].bounds);

        return bounds;
    }

The problem with this method is that bounds do not take into account rotation. I'd like the points to track the points on the game object regardless of rotation.

I had also considered placing a number of game objects within the prefab which served as each point, but I'd like to be able to do this programmatically.

CodePudding user response:

If I understand correctly you are looking for those min/max bounds points regardless of the parent objects orientation.

One general "issue" with the bounds is that they will always be world axis aligned.

So what you could do is

  • store parents rotation

    var rotation = transform.rotation;
    
  • reset parents rotation

    transform.rotation = Quaternion.identity;
    
  • now calculate the bounds

    var renderers = GetComponentsInChildren<Renderer>();
    var bounds = renderers[0].bounds;
    for (int i = 1; i < renderers.Length; i  )
        bounds.Encapsulate(renderers[i].bounds);
    
  • calculate the points (from the image I assumed XY for now but you can adjust accordingly)

    Vector2 center = bounds.center;
    Vector2 min = bounds.min;
    Vector2 max = bounds.max;
    
    Vector2 left = center:
    left.x = min.x;
    
    Vector2 right = center;
    right.x = max.x;
    
    Vector2 top = center;
    top.y = max.y;
    
    Vector2 bottom = center;
    bottom.y = min.y;
    
  • convert them into local space of the parent

    left = transform.InverseTransformPoint(left);
    right = transform.InverseTransformPoint(right);
    top = transform.InverseTransformPoint(top);
    bottom  = transform.InverseTransformPoint(bottom);
    
  • apply rotation back to parent

    transform.rotation = rotation;
    
  • convert again into world space (if needed at all)

    left = transform.TransformPoint(left);
    right = transform.TransformPoint(right);
    top = transform.TransformPoint(top);
    bottom = transform.TransformPoint(bottom);
    

This way you get clean(er) world space bound positions, always calculated in a world axis aligned space but then rotated back to the actual orientation of the parent

  • Related