Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Fitting an instantiated prefab inside a cube?

Discussion in 'Animation' started by Fotofobia, Aug 8, 2017.

  1. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    Hello all: I am using vuforia to instantiate a 3d object once it finds a proper imageTarget (info not completely relevant since the problem is not related to Vuforia).

    My questions is this: Once I instantiate a Prefab (clone) of an object, I need it to fit inside the boxcollider of the gameObject representing the image Target.

    Unfortunately I can't control the quality of the imported objects to standarize the size because they are created by different users in different systems, all I get is the .OBJ file.

    Therefore, whenever I run the app, some of my 3d models appear insanely large, others very small.

    I've read all the available answers about this issue but I just can't seem to find the right solution to my problem. Any help will be greatly appreciated.
     
  2. RevoltingProductions

    RevoltingProductions

    Joined:
    May 2, 2017
    Posts:
    37
    More than likely the source files were created in centimeters or inches and then exported without taking the scale unit of unity (meters) into account. First identify if this is the case, then you could write code that would check the scale of the import and adjust it if necessary. Conversely you could mandate a process for your contributors that uses meters and proper scale.
     
  3. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    Thanks for your reply.

    So, this means there is no way to programatically fit a 3d object inside another one?
     
  4. RevoltingProductions

    RevoltingProductions

    Joined:
    May 2, 2017
    Posts:
    37
    No, there is almost certainly a way to code for a scale correction. You would first have to know what a potentially wrong scale would be. Perhaps a line of code that checks to see if the character's scale falls out of a particular range. You may have to use something like a raycast to measure the modle to find its relative height then scale appropriately. For further info you should post some screen shots or something more to go on.
     
  5. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    Screenshots - ok. The first creenshot shows the CloudReco object, on top of it is the BoxCollider delimiting the ideal size of the 3d object, and leftmost is the object I want to fit inside the cube.

    Captura de pantalla 2017-08-10 a la(s) 3.06.42 p.m..png

    This is the code to spawn the 3d object
    Code (CSharp):
    1.         private void OnTrackingFound()
    2.         {
    3.  
    4.  
    5.  
    6.  
    7.             Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
    8.             Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
    9.  
    10.  
    11.             Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
    12.  
    13.  
    14.             if (controladorPanel.panelVisibile)
    15.             {
    16.                 return;
    17.             }      
    18.             infoUnit pregunta = valoresEstaticos.currentProject.getInfoUnitByTargetName (mTrackableBehaviour.Trackable.Name);
    19.  
    20.             if (pregunta == null) //no tenemos ninguna infoUnit acerca de este trackable
    21.                 return;
    22.  
    23.             if (pregunta.vuforiaTargetName == mTrackableBehaviour.Trackable.Name)
    24.  
    25.  
    26.             {
    27.  
    28.  
    29.                 print ("TrackableName: " + mTrackableBehaviour.Trackable.Name);
    30.                 //ve por la pregunta y despliega el panel con la pregunta.
    31.                    
    32.                 GameObject modelo =  (GameObject) Instantiate (Resources.Load ("Prefabs/" + pregunta.modelName), PuntoAparicion.transform.position, PuntoAparicion.transform.rotation); //PuntoAparicion = an object at the center of the boxcollider
    33.  
    34.                 modelo.transform.SetParent (mTrackableBehaviour.transform);
    35.  
    36.  
    37.                 modelo.transform.localScale += mTrackableBehaviour.transform.lossyScale; //  new Vector3 (1f, 1f, 1f);
    38.                 //modelo.transform.localScale += Vector3.one * height / 8f;
    39.  
    40.                 modelo.SetActive (true);
    41.                 modelo.name = "modelo";
    42.  
    43.             }  
    44.         }
    Screenshot 2: shows the actual screen when the image target is found. You can only see the inner elements of the 3d model, because its size is immense.


    Captura de pantalla 2017-08-10 a la(s) 3.10.45 p.m..png

    Thanks
     
  6. RevoltingProductions

    RevoltingProductions

    Joined:
    May 2, 2017
    Posts:
    37
    So what is the scale of that object when it is imported? Look at the model panel of the inspector window. If the model was created in centimeters and exported without the correction to the FBX then the scale will be exactly 100 times the correct size. Scale it down to .01 and if that fixes it then you know what to do with your code to make future corrections.

    If you have a really variable set of models where you have no idea if they are ever going to modeled correctly or not I suppose you could put a function in start() that raycasts from the camera and if it detects the model before it detects the bounding box then it scales the model down. Again, it would be better if you just had a standardized modeling practice, but that would be a viable hack.
     
  7. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    The scale of *this* particular object is 0.00345 --- but the scale of others is 2 (for example).

    Like I said, I have no control over the 3d models, they are created by different teams, different programs... I got them all to agree on the OBJ format, I doubt I can convince 50 different teams to utilize same scale and metric systems :(

    My problem is not manually scaling them, my problem is that when I spawn them they appear with localScale 0.0.0 and "scaling" them according to the scale of the boxCollider gives the result you saw in screenshot 2 - on the other hand, It's not practical to "hardcode" the appropiate scale for each model.

    The models are not in scene until the user identifies an augmented reality target, and then they are spawned...I am not experienced enough to create that raycast method you are describing :(

    Thanks for your valuable input, I hope we can find a solution to my dilemma.
     
  8. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,195
    You can get the bounds of the mesh from either the mesh renderer or the mesh collider. That gives you an approximation of the scale.

    So you'd spawn the object, check it's bounds, and increase/decrease it's scale so it roughly fits the box collider you want it inside.
     
  9. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    That sounds AWESOME!
    .
    .
    How do I do it? Please excuse my ignorance, I am not *that* good in Unity...yet ;)
     
  10. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,195
    Say you have targetArea which is the box you want to fit things into, and model which is the box you're putting in there. Then it'd be something like:

    Code (csharp):
    1. var targetCollider = targetArea.GetComponent<BoxCollider>();
    2. var modelMesh = model.GetComponent<MeshRenderer>().sharedMesh;
    3.  
    4. var targetScale = targetCollider.bounds.size;
    5. var modelScale = modelMesh.bounds.size,
    6.  
    7. // we want to re-size the model to fit in the target. But since we don't know the shape of the model,
    8. // and we don't want to stretch it, we want to resize it to the smallest of the x, y and z differences in
    9. // scale between the target and the model
    10.  
    11. var xFraction = modelScale / targetScale;
    12. var yFraction = modelScale / targetScale;
    13. var zFraction = modelScale / targetScale;
    14.  
    15. var fraction = Mathf.Min(xFraction, yFraction, zFraction);
    16.  
    17. //Honestly it's late and I'm too tired to see if you need to multiply or divide here. It's one of those. :P
    18. model.transform.localScale /= fraction;
    You'll need to do some adjustments for your case, but that's the basic idea. Note that collider.bounds and mesh.bounds is the same concept, an axis alligned box that fits the entire thing, just for colliders or bounds.

    If you're going long term, you'll want something more complex. This solution will make things that have a shape that's closer to the square be scaled up larger, while oblong things will be scaled smaller. You can experiment with using the average of the fractions or whatnot.


    Final piece of advice - you should really use English for variable and method names, so other non-Spanish people can read your code. You'll have a lot of trouble getting help or advice - I have no idea what half your code's supposed to do, since I can't read it.
     
  11. Fotofobia

    Fotofobia

    Joined:
    Mar 31, 2017
    Posts:
    10
    Thanks for your input, and noted on your observations. I will try it later today.
     
  12. eaquino_unity

    eaquino_unity

    Joined:
    Aug 13, 2019
    Posts:
    13
    it´s works?