I want to arrange 3D objects in a row but i need to make sure they have the same xsize how can i do this with a script
//Array of objects
public GameObject[] objs;
// Use this for initialization
void Start()
{
//Loop through the array
for(int x = 0; x < objs.Length -1; x ++)
{
//check if the object is the right size
if (objs[x].transform.localScale.x == 1/*Change this number to whatever you need*/)
{
//Object is that size
print("Object \"" + objs[x].name + "\" is the currect size!");
}
else
{
//Object is not that size
print("Object \"" + objs[x].name + "\" is NOT the currect size! the object size is : " + objs[x].transform.localScale.x);
}
}
}
i mean objects that have different sizes when the scale is the same, i know how to change the scale but not how to get the real size of an 3D object.
The size of an object is somewhat arbitrary. A GameObject doesn’t have a size, just a position, rotation and scale. If you’re talking about the size of the mesh renderer, then you can get the bounds of the renderer which should approximate the size of the mesh closely enough: Unity - Scripting API: Renderer.bounds
I am talking about the mesh. I have downloaded the Rocks pack. The .obj files all have different size now i wonder how “scale” them so they have all one size at x without editing all of them.
That’s a late answer to the other posts.
Like @kru suggested, you should use the object’s bounds.
It’s just some kind of normalization process, which takes place on the largest axis (only one axis to keep proportions).
The bounds are represented by an AABB, an axis aligned bounding box and are determined by the actual mesh.
So, the steps are:
- get the total bounds, e.g. B(10f, 25f, 16f) whereas scale is S(1f, 1f, 1f)
- find the largest axis value, which is 25 in this example
- “normalize” by dividing the scale by that value: S’(0.04f, 0.04f, 0.04f) so that the bounds become approx. B’(0.4f, 1f, 0.64f)
The mesh is now scaled to fit into an unit cube.
Add another factor to the result (or during calculation) to scale it for your needs.
Will be immediately added to my utitlies btw, never had the requirement to do such thing but always a nice to have. ![]()
I have a vague idea how that script would look like.
Maybe a function that takes the Gameobject and scales it . However i would not know how to deal with the bounds like finding the biggest or multiplicate that with a Vector3.
If you make a script to add it to your utitlies please share it then. This is a reoccuring problem for me last time i solved it by fixing all my own blends to one size after futily trying to make the script
Actually, when I said immediately, I meant I’d take note of it to implement it when I’m done with other stuff that I’m working on, as I usually take a lot of time to think about my personal preference to implement such things.
In its simplest form:
- you pass in a Renderer (or several renderers)
- get the bounds (if you passed multiple bounds, you want to combine them to get total bounds - there’s a utitlity method for that, I just cannot remember the name atm - I’ve written something similar at work though, so I know it does exist)
- do the math mentioned in the previous post
A more complex one would either accept a renderer, a component in general (or specificly a transform) or a GameObject and might offer more functionality, some ideas are:
- pass the instance of the type you chose for the overload
- have additional parameters that allow you to set a rule/policy to determine how to treat the object, e.g.:
=> get the root object first in order to get all renderers in the object’s hierarchy,
=> or simply start to get all renderes starting with the received object (or the component’s object respectively)
=> allow to specify the desired size of bounds / with or without keeping proportions
I made this now and did try it but it does not work. one i got negative values on ma and 2 the sizes are not even.
public static void normalizeassetx(GameObject asset) {
var rend = asset.GetComponent<Renderer> ();
Bounds bound= rend.bounds;
float ma;
float sizer=10;
if (bound.max.x >= bound.max.y) ma = bound.max.x;
else ma = bound.max.y;
ma = ma / sizer;
if (ma < 0) ma *= -1;
pre ("max" + ma, "scale " + 1 / ma);
asset.transform.localScale = new Vector3 (1 / ma, 1 / ma, 1 / ma);
}
Okay i managed it bound.size.x was what i needet:
public static void normalizeasset( GameObject asset) {
var rend = asset.GetComponent<Renderer> ();
Bounds bound= rend.bounds;
float ma;
float sizer=10;
if (bound.size.x>= bound.size.y&& bound.size.y >= bound.size.z) ma= bound.size.x;
else if (bound.size.y >= bound.size.z && bound.size.z >= bound.size.x) ma = bound.size.y;
else ma = bound.size.z;
ma = ma / sizer;
pre ("max"+ma, "scale "+1/ma);
asset.transform.localScale= new Vector3(1 / ma, 1 / ma, 1 / ma);
}
public static void normalizeassetx(GameObject asset) {
var rend = asset.GetComponent<Renderer> ();
Bounds bound= rend.bounds;
float ma;
float sizer=10;
if (bound.size.x > bound.size.y) ma = bound.size.x;
else ma = bound.size.y;
ma = ma / sizer;
if (ma < 0) ma *= -1;
pre ("max" + ma, "scale " + 1 / ma);
asset.transform.localScale = new Vector3 (1 / ma, 1 / ma, 1 / ma);
}
object1.transform.localScale = new Vector3(object2.transform.localScale.x, object2.transform.localScale.y, object2.transform.localScale.z);