I have a script here that I found in a tutorial for making spherical gravity setups a la Super Mario Galaxy. My setup is that this script is in a Python Logic Brick attached to a Collision sensor that detects if the player or other objects are in the radius of a sphere, causing the objects with a certain property gravity to drop to the center of the spherical area.
I don’t attach this logic to the planetoid itself but rather to static ghosted 3D models that envelop it like a gravitational field so I can use them similarly to a near sensor but with a little more control over where things are detected since I can actually model the area where gravity will work.
So what I need now is to rework this script for other shapes and types (such as local linear gravity and cylindrical-shaped gravity) also controlled by this same method, but I can’t figure out how to do it by myself.
For local linear gravity basically I need it such that the gravity field pulling on the object pulls it linearly along the field’s local Z axis. For cylindrical gravity it needs to work like the spherical one but only on 2 axes (the field’s local X and Y) instead of all 3.
Thanks for any help!
Spherical Gravity Script:
from bge import logic
from mathutils import Vector
cont = logic.getCurrentController()
own = cont.owner
scene = logic.getCurrentScene()
for obj in scene.objects:
if "gravity" in obj:
pull = Vector(obj.getVectTo(own)[1])
pull.magnitude = own["gAmount"]
obj.applyForce(pull)
player = scene.objects["Player"]
align = own.getVectTo("Player")[1]
player.alignAxisToVect(align,2,0.5)
As you see this does not belong to a shape but to a formula.
Your logic constantly calculate the force and applies it to the object.
Linear gravity: Apply a constant force to the object
Center gravity: Apply a force towards a defined center
Cylindrical gravity?: I guess you calculate a force towards the neares point on the cylinder’s axis.
The result is always a force (with length and direction). The input can be anything (e.g. distance to a something, orientation, size …).
Additionally you might want to skip/include objects to apply the force too. Typically this is done to save processing time e.g. when the force would be too small to be noticed. The inclusion/exclusion calculation should be less expensive than calcuationg and applying the force.
For the planar gravity specifically I’m looking for how to implement locally-pointing vectors (like I want to create a vector that points in the object’s local Z axis direction). I’ve been trying Vector(0,0,1), but that only makes it point in the global Z direction.
EDIT: Why is it that as soon as you ask for something you figure it out yourself?
[sigh]
Anyway here’s how I modified the spherical gravity code to make it planar:
Planar Gravity Script:
from bge import logic
from mathutils import Vector
cont = logic.getCurrentController()
own = cont.owner
scene = logic.getCurrentScene()
for obj in scene.objects:
if "gravity" in obj:
pull = Vector(own.getAxisVect((0, 0, -1))) # Creates vector pointing on the local -Z axis
pull.magnitude = own["gAmount"] # Gravity strength controlled by game logic property
obj.applyForce(pull)
player = scene.objects["Player"]
player.alignAxisToVect(-pull,2,1) # Aligns player object to gravity axis vector
So I’ve run into a second snag with my scripts. For the spherical gravity I want to have a Boolean game property that when marked True inverts the gravity such that the player and other objects affected by the magnetic field are pushed away from the field’s center point and orientated inversely to compensate.
As a visual, if “normal” gravity has the player walk along a spherical planetoid, then “inverted” will allow the player to walk along the inside of a spherical room. Watch this video to see what I’m talking about (at time 12:56 in):