x


The REAL size of an object.

I know the rough size of an object can be calculated from the collider.bounds, but I want to know if there is a way to get the correct width/bounds of an object, for a sphere collider that would be the radius, for a box, it would be the extent (or the bounds if possible). The reason I want this is because I'm building an RTS game which need to show the life of each object, currently I'm using collider.bounds, but it doesn't work so well because the width changes every time I rotate the object.

I can probably just do a lookup on what collider and it is and go from there, but that would require some Collider as BoxCollider stuff, which isn't go so easy on the CPU if you got a lot of units.

Does anyone know how to do this?

more ▼

asked Nov 18, 2009 at 07:25 PM

TowerOfBricks gravatar image

TowerOfBricks
3.9k 52 54 81

(comments are locked)
10|3000 characters needed characters left

3 answers: sort newest

I'm not sure what you meant by "show the life of each object" - do you mean the hit points of the object are calculated from the size? If you clarify this maybe we can suggest an alternative approach.

As to your original question: if the dimensions of the object don't change then it doesn't really matter how expensive the operation to calculate the area is, because you'd only have to do it once. You might even do it in the editor (with an editor script or by hand) for that matter and store it on the prefab. But if that's too fancy, you could calculate it when the object is first created at runtime and store it on an instance variable.

Even if you need to RE-calculate the area for some reason, again you can store it on the gameObject and only recalculate it when strictly needed. At that point the expense is going to be so small that I wouldn't worry about the additional cost of figuring out which type of collider you have. I'd only worry about it if you needed to calculate it multiple times per second.

As you seem to have realized, the dimensions of the collider should not change as the object is rotated, as long as you use the parameters for that type of collider. For example, BoxCollider.size is expressed in the object's local coordinates. Contrast this with Collider.bounds, which is the bounding box in world space. As you found, it is not a good way to calculate the area unless your object is axis-aligned.

Addendum: In the comments you indicated that you aren't computing a numeric area per se, you are trying to display an overlay bar of the correct width. I'll suggest two ways to do this.

  1. A good non-mathematical approach would be to simply add the bar as a small polygon (preusmably a quadrilateral) to the unit itself. (Either make it a child gameobject of the unit, or make it follow the unit around.) That way the bar would move around with the unit, and get smaller as it moves further away. Then you would just need to billboard the polygon so that it always faces the camera. You would get for free a cool effect where the health bar would be obscured by objects in front of it... But if you want the bar to always be visible, you could change the bar's shader to make it always draw on top, and you should in either case use a shader that is self-lit, not reflecting lights in the scene.

  2. If you prefer to do it mathematically though, what you need is the size of the unit (which we discussed above) after it has been projected by the camera onto the screen. A quick approximation of this would be to take a number representing the size of the unit (could be computed from the collider as already discussed, or just assign a "health bar width" to each type of unit manually at design time.)

Now we just need to scale the health bar using the distance from the camera. Have a look at Camera.WorldToScreenPoint, which tells you where on the screen a point in the world would be drawn. You can use this to see where to draw the bar, and you would need to scale the width of the bar depending on how far away it is from the camera.

I hope this gives you some ideas... You could also try searching the Unity discussion forums for "health bar" to see what other people have come up with, or what problems they ran into.

more ▼

answered Nov 18, 2009 at 09:10 PM

Bampf gravatar image

Bampf
5.6k 14 48 70

Ok, I will make my question a bit more clear: The collider.bounds returns a box containing the object which is axis aligned, I want to have a box around the object but it should be aligned to the local space. But I guess I will have to pre compute the box for all objects at startup as you said, and then rotate it during runtime depending on the rotation of the object (the width wont need changing though).

Nov 19, 2009 at 03:27 PM TowerOfBricks

PS: You know in all RTS games you see a thin green line over each unit showing the life, I need to calculate the width of that line for each unit, since I building will have a much longer line than a machine gun guy.

Nov 19, 2009 at 03:30 PM TowerOfBricks

Ah, I misunderstood what you were asking. I thought you were trying to compute the area as a number. Precomputing the size will only work if the viewed size of the object doesn't vary. For example, if the game is 2D or if you are using isomorphic projection. I will add to my original answer to discuss.

Nov 19, 2009 at 08:11 PM Bampf
(comments are locked)
10|3000 characters needed characters left

Is there some reason mesh.bounds won't work for you?

more ▼

answered Nov 18, 2009 at 11:37 PM

Jessy gravatar image

Jessy
18.3k 208 178 296

(comments are locked)
10|3000 characters needed characters left

The reason the bounds size changes when you rotate the object is that the bounds represents an Axis-Aligned Bounding Box (also known as an "AABB").

If you want to get a bounding sphere, you could scan through all the object's mesh vertices to find an average vertex position (the sphere centre) and the vertex which is furthest away from the average, (which gives you the sphere's radius).

See the Mesh Documentation for an example of how to quickly loop through every vertex in your mesh.

There's a chance that your average vertex position may not be at your object's local (0,0,0) position, so you'll need to use Transform.TransformPoint() to convert it to world-space to find your real boundingsphere centre point for the gameObject.

You then have the object's bounding sphere centre position and radius!

more ▼

answered Nov 18, 2009 at 08:52 PM

duck gravatar image

duck ♦♦
48k 135 254 494

(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x9401
x3239
x700

asked: Nov 18, 2009 at 07:25 PM

Seen: 9258 times

Last Updated: Nov 18, 2009 at 07:25 PM