- Home /
How to measure the height of a stack of objects?
Hello. I'm creating a 2D block stacking game where you instantiate blocks from a x-axis translating spawner object. The problem I'm facing is when the stack gets too high and close to the spawner, I need to move the spawner and game camera up on the Y-axis. Is there a way to measure a stack of prefabs to get their height so I know when to move my camera and spawner? I'm working in C#. Thanks in advance.
If rely purely on physics (so you don't have an internal way of keeping track of where each block is), then the most straightforward, but probably not most efficient way, would be to cast a ray downwards every width of block. the shortest ray gives you the max height of your stack.
Answer by Glurth · Jul 07, 2017 at 02:19 PM
I'll assume you have a record, or array of all the dropped blocks: loop through all the dropped blocks (exclude the still "falling" blocks by checking their velocity), and check their position. Note the block with the largest position.y value, and add half of that blocks height to this value to get the height of the stack. (if blocks vary in size, do the half-block height addition FIRST, and note the highest value of that.) Note: this assumes the "bottom" of the stack is at y=0, if not, you will need to adjust the result to compensate.
Better yet, you can store the hieghtOfTheStack, and have each block (possibly) update this value "OnCollision".
Thanks this definitely helps. I don't have the prefabs instantiating in an array yet but perform that first. In a scenario where blocks fall but remain on the platform and end up rotating, could this method still work? I suppose half the height wouldn't be perfect but enough to still know when to move the camera. I'll give this a shot today and see how it goes thanks.
AH! the "half height" would indeed no longer be accurate if the blocks rotate. You could compute the "hieght" of rotated object, but given this new info, I would probably start looking at Cherno's suggestion regarding using raycasts. Then again, since you don't really need perfect accuracy it might work ok.
Answer by Xeonproc · Jul 07, 2017 at 03:47 PM
I think possibly using Bounds may be the best solution as I can check the height of the parent object that contains all the block children. I've added some code to the solution that is part of the way there but is not increasing the parentBounds.max.y value as I add to the stack. Any ideas? Code below.
if (Input.GetMouseButtonDown(0)) {
Instantiate (fallingBrick, spawnPosObj.transform.position, Quaternion.identity, parentStack.transform);
var parentBounds = GetMaxBounds (parentStack);
Debug.Log (parentBounds.max.y);
}
}
Bounds GetMaxBounds(GameObject g) {
var b = new Bounds(g.transform.position, Vector3.zero);
foreach (Renderer r in g.GetComponentsInChildren<Renderer>()) {
b.Encapsulate(r.bounds);
}
return b;
}
oh, bounds, yeah, that's better....
foreach (Renderer r in g.GetComponentsInChildren<Renderer>())
shouldn't this be:
foreach (Renderer r in parentStack.GetComponentsInChildren<Renderer>())
edit: oops, I see it's your passed parameter... never$$anonymous$$d.. my bad.
One other issue I see though... you don't check to see if the block is "still falling".
Thank you for the correction. How would I check for a block being stationary? Apologize, I'm still very much a newbie.
I made a few changes to try and deter$$anonymous$$e the stackHeight but it is capping at 7 for some reason.. Up for a Skype call? LOL
if (Input.Get$$anonymous$$ouseButtonDown(0)) {
Instantiate (fallingBrick, spawnPosObj.transform.position, Quaternion.identity, parentStack.transform);
var parentBounds = Get$$anonymous$$axBounds (parentStack);
var stackHeight = parentBounds.max.y - parentBounds.$$anonymous$$.y;
Debug.Log (stackHeight);
}
}
Bounds Get$$anonymous$$axBounds(GameObject g) {
var b = new Bounds(g.transform.position, Vector3.zero);
foreach (Renderer r in g.GetComponentsInChildren<Renderer>()) {
b.Encapsulate(r.bounds);
}
return b;
}
I assume you are using rigidbodies on your blocks. That component has a member called velocity. if that is not Vector3.zero (or close), the block is still moving. https://docs.unity3d.com/ScriptReference/Rigidbody-velocity.html
So the parentBounds.extents DOES change? I suggest lots of Debug.Log commands in your loop, so you can see exactly what's happening in there. That usually how I figure out what it is that I have overlooked.
Your answer
Follow this Question
Related Questions
How to use AddForce and Velocity together 1 Answer
How to precisely control a character through scripts while still using unity collisions? 1 Answer
BoxCollider2d.bounds.Intersects Not Working 2 Answers
How to make Two colliders, don't collide, but still be able of interact with each others 2 Answers
Where should I call Physics2D.Raycast ? 0 Answers