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
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.
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.
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.