Tuesday, April 24, 2012

Game Engine versus Game Programming

I worked up some starting prototypes of DemolitionFX in Unity last night (mostly just working with beam primitives and joints..trying to get realistic structures with destructible joints).  Was very neat.  Didn't realize until towards the end that my primitive beams were WAY off scale in terms of size....my beams were some 120 feet long in some cases (intended them to be only 10-12 or so) and was effecting the physics a bit.  While I worked with several physics engines in the past (Phys2D, Box2D, etc) and am comfortable with concepts like adding force to rigid bodies, I was pleasantly surprised by some of the tools that Unity brought to the table as a true 'game engine'.  Example.  I created a small sphere that I placed 'near' my structure to act as a bomb.  Pressing the space bar would 'detonate it, generating an explosion.  Unity provided me some neato functions to help propagate that explosive force to my structure:

function explode(){
 var explosionPos : Vector3 = transform.position;
    var colliders : Collider[] = Physics.OverlapSphere (explosionPos, radius);
    for (var hit : Collider in colliders) {
        if (!hit)
        if (hit.rigidbody)
            hit.rigidbody.AddExplosionForce(power, explosionPos, radius, 3.0);
Essentially, the physics engine provides me with list of rigid bodies that are overlapped by a sphere of whatever radius and I can then use a super handy function to 'AddExplosiveForce' to each of them...theoretically exactly on their bodies where the explosion should effect them.  And..the explosive force will fall off linearly with the distance to the rigid body.

Here is the same code from my old JavaFX version of DemolitionFX:

  public static void explosion(World world, Vec2 position, float power, int maxApply)
         AABB  aabb = new AABB();
         Vec2 vMin = position.clone();
         vMin = vMin.add(new Vec2(-1f*(float)power, -1f*(float)power));
         Vec2 vMax = position.clone();
         vMax = vMax.add(new Vec2(1f*(float)power, 1f*(float)power));
         aabb.lowerBound = vMin;
         aabb.upperBound = vMax;
         Shape[] shapes = null;
         shapes = world.query(aabb, maxApply);
         for (int i = 0; i < shapes.length; i++)
            Body b  = shapes[i].getBody();
            if(b.getUserData()==null || b.getUserData() instanceof String){
            Vec2 explosionClosePoint = new Vec2(0f,0f);
            Vec2 bodyClosePoint = new Vec2(0f,0f);
            Shape bodyShape = b.getShapeList();

              PolygonDef sd = new PolygonDef();
              sd.density = 0.0f;
              sd.friction =0f;
              BodyDef bd= new BodyDef();
              bd.position = position.clone();
              Body body= world.createBody(bd);
              Shape explosionShape = body.createShape(sd);
          float dist = Distance.distance(explosionClosePoint, bodyClosePoint,
explosionShape, body.getXForm(),
bodyShape, b.getXForm());
            Vec2 fv = bodyClosePoint.clone();
            fv = fv.sub(position);
            fv = fv.mul(5500+(float)power * 5000f);
            b.applyForce(fv, bodyClosePoint);

Essentially, I generate  rectangle around the position of my explosion....get a list of rigid bodies that overlap it...but I have to create a fake 'explosion' object in order to find the closest point from that object to each of the overlapping objects...and then calculate and apply the appropriate force.  Also...I did not take into consideration the distance between the explosion and the object...if it was in the rect...it got the same force as any other object in the rect.    The extra code I had was not THAT much extra work...but I was amazed that Unity provided me exactly what I needed with no fuss and muss.

No comments:

Post a Comment