- Home /
Getting object to destroy on impact
I modeled a simple brick in Blender and then used Cell Fracture to create a new prefab that I instantiate when the brick is hit by a sphere to simulate the brick being destroyed.
The bricks are currently suspended in mid air (intentional) and they are destroyed on being hit by the sphere and the debris prefab is instantiated and falls, but the debris prefab doesn't break apart until it hits the ground or another object. I'd like the debris prefab to break apart as soon as it's instantiated to simulate the brick being broken apart by the sphere.
I'm new to Unity, so my best guess is that I need to use an Explosion Force to simulate the sphere breaking the brick? Because the debris prefab isn't being broken apart because technically it was never hit by the sphere? Or am I missing something else? Thanks!
Ok, now I understand it! I haven't worked with ExplosionForce or collider points yet but I think I get their basic function. That particular script works perfectly, I just need to tweak the numbers and experiment to see what kind of secret sauce you can do with ExplosionForce.
I liked the simplicity of the first suggestion but this is a Breakout-style game so the bricks are suspended in mid-air. I'll try experimenting with it to try and find if there's a way to keep the debris prefab suspended but still be broken apart by the ball and act accordingly. I imagine the simpler approach would be easier on performance than having so many things be instantiated.
Thank you both again!
Answer by aldonaletto · Jul 22, 2013 at 03:52 AM
In fact, the original collision doesn't affect the debris because they were created after it. You should add a rigidbody and a collider to each one of the debris, and apply forces to make them break apart. A good solution is to child the debris to an empty object (the debris prefab) and use GetComponentsInChildren in order to get a list of all pieces, then apply the ExplosionForce to each one - like this (brick script):
var debrisPrefab: GameObject; // drag the debris prefab here
var force: float = 500;
var radius: float = 15;
function OnCollisionEnter(col: Collision){
// create replacement pieces:
var brokenBrick: GameObject = Instantiate(debrisPrefab, transform.position, transform.rotation);
var pos = col.contacts[0].point; // get hit point
// get a list with all rigidbodies in the broken brick object:
var debris: Component[] = brokenBrick.GetComponentsInChildren(Rigidbody);
// add explosion force to them according to their positions:
for (var rb: Rigidbody in debris){
rb.AddExplosionForce(force, pos, radius);
}
Destroy(gameObject); // destroy original brick
}
EDITED: This is the C# version (hope it's ok - the C# compiler is evil!):
using UnityEngine;
using System.Collections;
public class ExplodeBrick : MonoBehaviour {
public GameObject debrisPrefab; // drag the debris prefab here
public float force = 500;
public float radius = 15; // explosion force decreases to zero at this distance
void OnCollisionEnter(Collision col){
// create replacement pieces:
GameObject brokenBrick = Instantiate(debrisPrefab, transform.position, transform.rotation) as GameObject;
Vector3 pos = col.contacts[0].point; // get hit point
// get a list with all rigidbodies in the broken brick object:
Component[] debris = brokenBrick.GetComponentsInChildren<Rigidbody>();
// add explosion force to them according to their positions:
foreach (Rigidbody rb in debris){
rb.AddExplosionForce(force, pos, radius);
}
Destroy(gameObject); // destroy original brick
}
}
I've been mainly working with C# so I'm having a bit of a problem translating this from JavaScript. Is it possible for someone to post these function in C#? ,I've been mainly working with C# so I'm having a bit of a problem translating this from JavaScript. Is it possible for someone to post these function in C#?
Converting this code to C# isn't so trivial, since there are many pitfalls: GetComponentsInChildren is generic, for..in becomes foreach and you mast cast Instantiate to the correct type.
Answer by robertbu · Jul 22, 2013 at 03:41 AM
There are multiple ways of doing most things in Unity. Add an explosion force to each fragment is one way. The strength of AddExplosionForce() is that it drops off linearly with distance. I don't think you need that here, so using AddForce() would work fine.
But let me suggest an alternate. Instantiate both the whole brick and the fragments at the same time. Make the whole brick a bit larger so that it hides the fragments. The whole brick would not have a collider. When any of the fragments gets hit, it can turn off the renderer for the whole brick (parent) exposing the fragments. That way the sphere is the thing that causes the fragments to fly creating breakage that better matches the sphere hit. You'll have to play with the mass of the sphere and the fragments to get the look you like.
Thank you both for the answers! I'll mess around with both solutions.