How to achieve this effect?

Hello,

How do you achieve realtime destruction the the game engine? For instance, if I have a car which has a damaged door, how would I make the door fling on its hinges depending on the velocity of the car. Here is a link to show the effect I am trying to achieve: https://www.youtube.com/watch?v=FtUhOdROmlo&list=PL8152A2F53ADC5F49

Thank you.

Use rays or collision detection for detect if the car is colliding, for get the velocity use the getLinearVelocity() with python, and finally for the deformation use shapekeys and use the velocity for the value of the shapekeys.

PD: I have no time in this moment for make a example, sorry.
PD2: this python function can also be useful

In that video, each car part was made as a separate object with a collision sensor that triggers shapekey action when a collision is detected. If you’re trying to get a more advanced looking effect then you can do what Carlo697 said, by getting the difference between the velocities of the collider and collided objects on collision.

I tried before to create actual “metallic looking” softbody deformation but my only issue was that the deformation springed back, and wasn’t permanent. (tried several “hacks” like creating constraints on the fly that holdup verts in places but it got bugged out allot.)

For the doors you could use rigid body constraints, but first the door and the car need to be separate objects.

Does the door need to be parented to the car? Because when I add rigid body physics to the door and parent it to the car the car flies and spins.

No, but when you setup the constraint, check mark “Linked collision”

this return the axis local with max impact (-Y) = impact frontal


from mathutils import Vector
import bge 
class Impact:
  def __init__(self, gob):
    self.gob = gob
    self.old = gob.worldLinearVelocity.copy()
    self.impact = Vector()


  def update(self):
    self.impact =  self.gob.worldLinearVelocity.copy() - self.old
    self.old = self.gob.worldLinearVelocity.copy()


  @property
  def magnitude(self):
    return self.impact.magnitude


  def getAxisImpact(self):
    xyz = self.impact * self.gob.worldOrientation
    axis = sorted([(n,abs(i)) for n,i in enumerate(xyz)],key=lambda v:v[1])[-1][0]
    realVal = xyz[axis]
    sign = "-" if realVal < 0 else "+" 
    return sign + "XYZ"[axis]




MAXIMPACT = 1.0


def m(c):
    own=c.owner
    if not "init" in own:
        own["init"] = 1
        own["impact"] = Impact(own)
        
    impact = own["impact"]
    impact.update()
    print(impact.magnitude)
    
    if impact.magnitude > MAXIMPACT:
        print(impact.getAxisImpact())
        
        # debug
        bge.render.drawLine(own.worldPosition,own.worldPosition+impact.impact*50,[1,0,0])

Thank you all for the helpful replies!