2
$\begingroup$

Based off of another tutorial, I'm trying to put together a script for an object that will apply a force to anything near it, essentially repelling it when the "near" logic brick is triggered.

from bge import logic

def _getForceMagnitude(distance, max_force, max_range):
    return (distance * (-max_force/max_range)) + max_force

def repel():

    scene = logic.getCurrentScene()
    cont = logic.getCurrentController()
    shield = cont.owner

    for obj in scene.objects:
        vec = obj.worldPosition - shield.worldPosition
        vec.magnitude = _getForceMagnitude(vec.magnitude, 10, 4)
        vec.applyForce(vec)
$\endgroup$
2
  • 2
    $\begingroup$ It would help to know what's not working, do you get any errors in the console? $\endgroup$
    – Mike Pan
    Dec 25, 2013 at 18:34
  • $\begingroup$ Sorry it took a while to respond. There are no errors being reported, but I do have another script so similar to this one to get planetary gravity. Could it be that the two are in conflict? $\endgroup$ Dec 27, 2013 at 16:45

2 Answers 2

1
$\begingroup$

I reworked the whole script from bottom up and came up with the solution that I needed. With this script, any object that triggers the near sensor will be pushed from the origin of the object with the near sensor. The from bge import render and render.drawLine(shieldLoc, objLoc, [0, 0, 255]) is just there to visually see the script when it triggers.

from bge import render
from bge import logic
from mathutils import Vector

def _getForceMagnitude(distance, max_force, max_range):
    return (distance * (-max_force/max_range)) + max_force

def main():
    cont = logic.getCurrentController()
    own = cont.owner
    scene = logic.getCurrentScene()
    #sensor and sensor location
    trigger = cont.sensors["Near"]
    shieldLoc = own.worldPosition

if trigger.positive:
    #iterate through all objects in range
    obj = trigger.hitObjectList
    for objList in obj:
        #location of each object and vecter
        objLoc = objList.worldPosition
        dist = own.getDistanceTo(objLoc)
        vec = objLoc - shieldLoc
        #applying vecter
        vec.magnitude = _getForceMagnitude(dist, 50, 25)
        objList.applyForce(vec)
        render.drawLine(shieldLoc, objLoc, [0, 0, 255])
main()
$\endgroup$
0
$\begingroup$

applyForce is only applicable to game objects. Currently you are trying to apply force to a variable (vec) that you created. Change the last line to

obj.applyForce(vec)

However, this will apply the force to EVERY object in the scene, not just the ones nearby which I don't believe is the behavior you want.

Also, I think you have a few issues with your script. I made some modifications below.

You could try using the following:

from bge import logic

def _getForceMagnitude(distance, max_force, max_range):
    return (distance * (-max_force/max_range)) + max_force

def repel():

    scene = logic.getCurrentScene()
    cont = logic.getCurrentController()
    shield = cont.owner

    #Create reference to near sensor
    near = shield.sensors["Near"]

    #Check if near sensor is positive
    if near.positive:
        #Get the object that triggered the near sensor
        obj = near.hitObject
        #Get the distance from the object to the shield
        dist = shield.getDistanceTo(obj)

        vec = obj.worldPosition - shield.worldPosition
        vec.magnitude = _getForceMagnitude(dist, 10, 4)
        obj.applyForce(vec)

I'm not 100% sure what the distance variable in the _getForceMagnitude represents so I put in the distance between the shield and the object that triggers the near sensor. Hopefully this helps.

$\endgroup$
1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .