BGE Python: applyForce problem

Hello there! I’m attempting to develop a script that checks the altitude of all objects in the scene, and if the altitude of an object is “sea level”, it’ll add a force to it multiplied by a few custom properties of the object in question. I haven’t coded the altitude check yet, as I’m having a rather serious problem with the code already. That is, the applyForce code isn’t working… Without it, the script works fine.

import GameLogic
from bge import logic
scene = logic.getCurrentScene()
cont = GameLogic.getCurrentController()
own = cont.owner

activate = cont.sensors["activate"]

if activate.positive:
    own['WORKING'] = 1.0
            #just a pre-check to see if the code's working.

    for target in scene.objects:
        if "FloatAmount" in target:
                   
            target.applyForce([0.0, 0.0, target['FloatAmount'] * own['force']], False)
                   # ^ here's the problem... This line simply doesn't work.  Both the properties ('FloatAmount' and 'force') are accounted for.  I can't seem to find a solution...

            target['FLOATING'] = 1.0
            #just another check to see if the code's working.

Yep. If I could get a solution to this, it would be greatly appreciated. Thanks!

I guess you didn’t looked at the console? or why are you using properties to see if the code works. Better

debug = 100   
         
def applyFloatingForcesToFloatingObjects(cont):
   if not allPositive(cont.sensors):
     return
   scene = cont.owner.scene
   floatingObjects = filterObjectsByProperty(scene.objects, "FloatAmount") #what does "FloatAmount" mean?
   
   commonUpForce = cont.owner["force"]
   for floatingObject in floatingObjects:
   	 calculateAndApplyUpForce(floatingObject, commonUpForce)
   
def calculateAndApplyUpForce(gameObject, commonUpForce):
  upForce = gameObject['FloatAmount'] * commonUpForce
  gameObject.applyForce([0.0, 0.0, upForce], False)
  if debug>=75: print("Applied up-force of {} to {}".format(upForce, gameObject))
  
def filterObjectsByProperty(gameObjects, propertyName):
  return [gameObject for gameObject in gameObjects
                     if propertyName in gameObject]
                      
def allPositive(sensors):
  for sensor in sensors:
    if not sensor.positive:
      return False
  return True

I rewrote your code to make it a bit more readable.
Please notice:

  • no need to import GameLogic and bge.logic. They both are the same modules.
  • no need to import them at all. You can get all data (for this code) from current controller
  • switched to module mode. It is really better. Please adjust your Python controller!
  • removed the useless property settings
  • added a switchable print statement (switch of by setting debug to 0)
  • check the console when/after running (Expect an upForce>0 at each frame)
  • be aware forces needs to be applied at all frames not just once
  • FloatAmount is a pretty weak name (can be read as: “Value of a float property”). Better call it “FloatingForce” or something that describes what it really means. When you think about descriptive names, you think about how to solve your ideas.
  • I added a function to check all senors (like an AND). So you do not need to know the names or the number of sensors
  • I did not test that. There might be some typos.

I hope this helps to solve your problem

Why is it better to use modules instead of internal scripts?

Its not better, its just cleaner code. The idea is only to run code that is needed at the time. Modules are a great way of calling sections you need. you can just run the file always to its entirety although you need to set up low resource consuming condition checks to see which parts need to run at what time.

CTBM

I wrote a comparison here: http://wiki.blender.org/index.php/Doc:/Tutorials/Game_Engine/ScriptMode_vs_ModuleMode.

Additional to that my experience tells me that people are using script mode because they found some old code and base on that. It does not mean that this code is bad.

Thanks for that Monster, I’ve never seen this page before and i practically live on the the API & Wiki site.

CTBM

Wow! Thank you! This is awesome! Unfortunately I’m rather gravely inexperienced in python, and I haven’t had much practice with modules, so I hadn’t thought of using them.
I used ‘FloatAmount’ because I wanted a custom property for objects separate from mass that I could use to control the “buoyancy” of an object under the effect of the script/module, but I seem to have trouble always typing “buoyancy” correctly, and I didn’t want to deal with a script failing from spelling errors when there were greater issues at hand. Silly, I know…
Anyway. Thank you, GREATLY! Hopefully this’ll get me off my lazy butt and learning modules. Unfortunately I haven’t gotten around to testing it as of yet (it’s 6AM here) but I shall.