Turn a vector into a float

Hi all!

I found some code by Social that calculates impact forces. I have integrated it into a script I am currently working on but I have come across a problem. To start with here is the code:

def collision(cn):
    ow  = cn.owner
    collision = cn.sensors["collision"]
    if collision.positive:
        linv_now = ow.getLinearVelocity()

        applied_vec = linv_now - ow["linv_before"]

        print ("For object:", ow.name)

        print ("--Impact magnitude:", applied_vec.magnitude)


        print ("--Direction vector:", applied_vec.magnitude)

        print ("") # Space
        #ow["health"] -= ???? < what to put here?
        ow["linv_before"] = ow.getLinearVelocity()


Now when my objects collide with anything this script outputs the force of the collision. The thing is, I would love to use this number so it can be subtracted from the objects health property (in the line I annotated with ???). I have tried a couple of approaches but I get a ‘cannot use with noneType’ error so I am guessing I need to convert it somehow…

Can anyone give me some pointers?

Many thanks


It sounds like you want the magnitude of the vector (which it looks like you know how to get).

Just a guess here, but you probably already tried using applied_vec.magnitude, and still got the noneType error. If this is the case I would look into ow[“health”], and make sure it is actually initialized (and not returning none).

import bge
def collision(cont):
    own  = cont.owner
    collision = [c for c in cont.sensors if isinstance(c, bge.types.KX_TouchSensor)][0]

    multiplier = 1
    if collision.positive:
        linv_now = own.getLinearVelocity()
        linv_before = own.get("linv_before", linv_now)
        applied_vec = linv_now - linv_before

        print ("For object:", own.name)

        print ("--Impact magnitude:", applied_vec.magnitude)

        print ("--Direction vector:", applied_vec.normalized())

        print ("") # Space
        own["health"] = own.get("health", 0.0) - applied_vec.magnitude * multiplier
        own["linv_before"] = own.getLinearVelocity()


Thanks for the replies, and it works a treat agoose!

A few (basic for you!) questions though:

First off, why do we need to construct a list of collisions, are we using the list entry itself in some way?

And what does the multiplier do? It will be useful to tune damage (i.e. use values below 1).

The collisions list returns a list of all the collision sensors attatched to the object’s controller, then retreives the first one in the list.
The multiplier basically allows you to change the strength of the damage.

how can work without .copy() ?

the two vectors (old and new) should be two vector identical!

now understand, i think which work when there a collision (without keep in count the speed)
the code (with get()) seem a bit old as syntax

No, I beleive getLinearVelocity() returns a copy of the vector, whilst worldPosition is a reference to that vector.

I had come to doubt that this could be…

…yes true:
you’re right;)

def player(cn):
    own = cn.owner

    if not "init" in own:
        own["vel"] = own.getLinearVelocity()
    print(  "----------------------"   ) 
    print(  own.getLinearVelocity()   )
    print(  own["vel"]   )
    print("difference",own.getLinearVelocity() - own["vel"] )


    own["vel"] = own.getLinearVelocity()

You do not need an “init” property. This is old style object initialization.
Just check for the existence of “vel” as this is the property the code is using.

“bean style syntax” is not old. It is just a style. The “property syntax” is another style (with the meaning of Python properties not BGE properties ;)).