Game Development Reference
In-Depth Information
Logically, when the bottom most block is destructed, then the whole pillar must fall apart
(unless you want Super-Mario-like blocks that float in the air). The question is how to tell
the physics simulator that each block in the pillar depends on the one below it, and hence
must be destructed when the dependency is destructed. This is the job of
scanDirection
,
which is a vector that starts from the center of the block and goes in the specified direction.
In case of the- pillar, this vector must point downwards with a magnitude greater than 0.5,
which is the distance between the center of the block and its bottom face. Before discussing
the mechanism of
scanDirection
, it is important to understand the dependency structure.
For each destructible, there is a list of other destructible objects that depend on it. When the
dependency is destructed, then all object in its
dependents
list must be destructed as well.
At the beginning of the game, and as we already know,
Start()
function is called. Upon
start, each destructible casts a ray with the direction and the magnitude specified in
scanDirection
. What the destructible tries to do by casting this ray is to find a dependency.
This dependency must be have
Destructible
script attached, which is checked in line 28. If
the condition is satisfied, the destructible which has cast the ray adds itself to
dependents
list inside the destructible which the ray hit. In case of the pillar shown in Illustration 69,
scanDirection
should have a value such as (0, -0.6, 0), so that each scan ray is cast down-
wards. As a result, each block will add itself to
dependents
list of the block below it, while
the bottom most block isn't going to be able to find any dependencies.
After building dependencies among building blocks, the next step is to freeze the block
so it does not get affected by physics simulation. Therefore, the
rigidbody.constraints
of the
block are saved in
original
, and then changed to
RigidbodyConstraints.FreezeAll
. This guar-
antees that both position and the rotation of the block are conserved up to the moment we
decide to allow them to be changed. The block remains frozen until
Destruct()
function is
called (or
Destruct
message is received). To destruct the block, the first thing to do is to free
it from any constraints by resetting
rigidbody.constraints
to its original value stored in
ori-
ginal
. After that, the destruction must be propagated to all dependencies by calling
Destruct()
for all elements in
dependents
list. However, it is better to delay the destruction by a tiny
amount of time, in order to give the sense of physical relation between the blocks. Finally,
it won't hurt if we send an informative message to all other script connected to the block,
telling them that destruction just happened. This makes it possible to do some relevant ef-
fects, such as playing sound or making some dust. Illustration 70 shows a simple building
constructed with destructible building blocks.