Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

dynamic loaded object fit to screen size

Discussion in 'Scripting' started by ki_ha1984, Aug 24, 2015.

  1. ki_ha1984

    ki_ha1984

    Joined:
    Aug 24, 2014
    Posts:
    111
    Hi,

    I developed i code which creates an object by reading the obj file and developing the mesh with this link, but problem is that in many cases the object is much more big than my character and camera, and my camera is inside the object. The object has scale 1.1.1.

    Now the question is how i can fit the object inside of the camera view ?
    Is there any possibility to read the object size in pixels ?

    Thank you in advance
     
  2. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
  3. ki_ha1984

    ki_ha1984

    Joined:
    Aug 24, 2014
    Posts:
    111
    Can you please provide me any sample code ?
     
  4. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    This should get you a long way. It's not complete, but I'm sure you can figure out the rest and learn a thing or two while you're at it.

    Code (CSharp):
    1.  
    2. private void PositionInView()
    3. {
    4.     const float DISTANCE_FROM_CAM = 50;
    5.     Vector2 padding = new Vector2(0.01f, 0.1f); //Distance we want to keep from the viewport borders.
    6.  
    7.     Bounds bounds = GetComponent<MeshFilter>().mesh.bounds;    //Get the bounds of the model - these are in local space of the model, axis aligned.
    8.     //Calculate the max width the object is allowed to have in world space, based on the padding we decided.
    9.     float maxWidth = Vector3.Distance(Camera.main.ViewportToWorldPoint(new Vector3(padding.x, 0.5f, DISTANCE_FROM_CAM)),
    10.         Camera.main.ViewportToWorldPoint(new Vector3(1f - padding.x, 0.5f, DISTANCE_FROM_CAM)));
    11.     //Calculate the scale based on width only - you will have to check if the model is tall instead of wide and check against the aspect of the camera, and act accordingly.
    12.     float scale = (maxWidth / bounds.size.x);
    13.     //Apply the scale to the model.
    14.     transform.localScale = Vector3.one * scale;
    15.        
    16.     //Position the model at the desired distance.
    17.     Vector3 desiredPosition = DISTANCE_FROM_CAM * Camera.main.transform.forward + Camera.main.transform.position;
    18.     //The max width we calculated is for the entirety of the model in the viewport, so we need to position it so the front of the model is at the desired distance, not the center.
    19.     //You will also have to keep rotation of the camera and the model in mind.
    20.     transform.position = desiredPosition + new Vector3(0, 0, bounds.extents.z * scale);
    21. }
    22.  
     
    Ghosthowl, mowax74 and Alex_F like this.
  5. andyastro

    andyastro

    Joined:
    Sep 17, 2015
    Posts:
    16
    Hi, Thomas, glad I found this reply of yours. I happen to have asked something similar recently, and now that I read your answer, I thought maybe this thread can be what I've been looking. However, I tried to adapt your code to my needs, without total success.

    I am trying to accomplish the inverse direction of what you have described to the OP: I have to decide in the runtime the "dolly zoom" distance of the perspective camera so a procedurally generated object of random shape fills into the screen. I use the object's bounds for reference, but I am not sure how to proceed from there. I've tried a bunch of formulas found in different somewhat-related threads, but none works perfectly (I need that when the object is small or big, the camera zoom accordingly so it fits equally the same). Any ideas? Thanks!
     
  6. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    Nothing a bit of trig' can't solve. You will need to improve a bit on it to work in all cases (when facing the back of the object for instance, or when the object is too wide to fit in the view), but I'm sure you can figure that out. The script will keep the camera's starting pitch and yaw, so you're not forced to look at the object dead on.

    Happy coding!

    Code (CSharp):
    1. void PositionCamera()
    2.     {
    3.         Bounds objectBounds = ObjectToView.GetComponent<Renderer>().bounds;
    4.         Vector3 objectFrontCenter = objectBounds.center - ObjectToView.transform.forward  * objectBounds.extents.z;
    5.  
    6.         //Get the far side of the triangle by going up from the center, at a 90 degree angle of the camera's forward vector.
    7.         Vector3 triangleFarSideUpAxis = Quaternion.AngleAxis(90, ObjectToView.transform.right) * transform.forward;
    8.         //Calculate the up point of the triangle.
    9.         const float MARGIN_MULTIPLIER = 1.5f;
    10.         Vector3 triangleUpPoint = objectFrontCenter + triangleFarSideUpAxis * objectBounds.extents.y * MARGIN_MULTIPLIER;
    11.  
    12.         //The angle between the camera and the top point of the triangle is half the field of view.
    13.         //The tangent of this angle equals the length of the opposing triangle side over the desired distance between the camera and the object's front.
    14.         float desiredDistance = Vector3.Distance(triangleUpPoint, objectFrontCenter) / Mathf.Tan(Mathf.Deg2Rad * GetComponent<Camera>().fieldOfView / 2);
    15.  
    16.         transform.position = -transform.forward * desiredDistance + objectFrontCenter;
    17.     }
    18.  
     

    Attached Files:

    Last edited: Sep 20, 2015
  7. andyastro

    andyastro

    Joined:
    Sep 17, 2015
    Posts:
    16
    Cool, many thanks for the detailed reply! I will take a look and do some try-and-error with code. If anything odd happens, I come back.
     
    Thomas-Mountainborn likes this.