I created several constraints (6DoF) with the following script:
import PhysicsConstraints as constr
import GameLogic
scene = GameLogic.getCurrentScene()
objList = scene.objects
stiffness = 500
MaxAngleLimit = 0.2
MinAngleLimit = -0.2
steer = objList['FrontAxisGhost']['steer']
CarBodyID = objList["CarBody"].getPhysicsId()
CarCenterID = objList["CarCenter"].getPhysicsId()
FrontAxisID = objList["FrontAxisGhost"].getPhysicsId()
RearAxisID = objList["RearAxisGhost"].getPhysicsId()
FRAxleID = objList["AxleFR"].getPhysicsId()
FLAxleID = objList["AxleFL"].getPhysicsId()
RRAxleID = objList["AxleRR"].getPhysicsId()
RLAxleID = objList["AxleRL"].getPhysicsId()
SteerLID = objList["SteerL"].getPhysicsId()
SteerRID = objList["SteerR"].getPhysicsId()
WheelFLID = objList["WheelFL"].getPhysicsId()
WheelFRID = objList["WheelFR"].getPhysicsId()
CarBody6DoF = constr.createConstraint(CarBodyID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
CarBody6DoF.setParam(3, 0.0, 0.0)
CarBody6DoF.setParam(4, 0.0, 0.0)
CarBody6DoF.setParam(5, 0.0, 0.0)
FAxis6DoF = constr.createConstraint(FrontAxisID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
FAxis6DoF.setParam(3, 0.0, 0.0)
FAxis6DoF.setParam(4, 0.0, 0.0)
FAxis6DoF.setParam(5, 0.0, 0.0)
RAxis6DoF = constr.createConstraint(RearAxisID,
CarCenterID, 12, 0, 0, 0, 0, 0, 0, 0)
RAxis6DoF.setParam(3, 0.0, 0.0)
RAxis6DoF.setParam(4, 0.0, 0.0)
RAxis6DoF.setParam(5, 0.0, 0.0)
FR_6DoF = constr.createConstraint(FRAxleID,
FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
FR_6DoF.setParam(3, 0.0, 0.0)
FR_6DoF.setParam(4, 0.0, 0.0)
FR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
FR_6DoF.setParam(15, stiffness, 1)
FL_6DoF = constr.createConstraint(FLAxleID,
FrontAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
FL_6DoF.setParam(3, 0.0, 0.0)
FL_6DoF.setParam(4, 0.0, 0.0)
FL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
FL_6DoF.setParam(15, stiffness, 1)
RR_6DoF = constr.createConstraint(RRAxleID,
RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
RR_6DoF.setParam(3, 0.0, 0.0)
RR_6DoF.setParam(4, 0.0, 0.0)
RR_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
RR_6DoF.setParam(15, stiffness, 1)
RL_6DoF = constr.createConstraint(RLAxleID,
RearAxisID, 12, 0, 0, 0, 0, 0, 0, 0)
RL_6DoF.setParam(3, 0.0, 0.0)
RL_6DoF.setParam(4, 0.0, 0.0)
RL_6DoF.setParam(5, MinAngleLimit, MaxAngleLimit)
RL_6DoF.setParam(15, stiffness, 1)
SteerFL_6DoF = constr.createConstraint(SteerLID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerFL_6DoF.setParam(3, 0, 0)
SteerFL_6DoF.setParam(4, 0, 0)
SteerFL_6DoF.setParam(5, 0, 0)
SteerFR_6DoF = constr.createConstraint(SteerRID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerFR_6DoF.setParam(3, 0, 0)
SteerFR_6DoF.setParam(4, 0, 0)
SteerFR_6DoF.setParam(5, 0, 0)
WheelFL_6DoF = constr.createConstraint(WheelFLID,
SteerLID, 12, 0, 0, 0, 0, 0, 0, 0)
WheelFL_6DoF.setParam(4, 0.0, 0.0)
WheelFL_6DoF.setParam(5, 0, 0)
WheelFR_6DoF = constr.createConstraint(WheelFRID,
SteerRID, 12, 0, 0, 0, 0, 0, 0, 0)
WheelFR_6DoF.setParam(4, 0, 0)
WheelFR_6DoF.setParam(5, 0, 0)
So the car body, front and rear axes are attached to the car center, front, rear, right, left axles are attached to the axes, two steering dummies are attached to the front axles and wheels themselves are attached to the steering dummies. Everything is fine and dandy so far.
However, now I want the front wheels to steer according to some action. I set up some logic bricks so that I have a property called steer that always decreases to the zero if nothing is pressed and if either A or left arrow is pressed it decreases down to some negative threshold value and if either D or right arrow is pressed it increases to the same positive threshold value.
I take that steer value from the front dummy object with steer = objList['FrontAxisGhost']['steer']
. However when I change the following:
SteerL_6DoF = constr.createConstraint(SteerLID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerL_6DoF.setParam(3, 0, 0)
SteerL_6DoF.setParam(4, 0, 0)
SteerL_6DoF.setParam(5, steer, steer)
SteerR_6DoF = constr.createConstraint(SteerRID,
FLAxleID, 12, 0, 0, 0, 0, 0, 0, 0)
SteerR_6DoF.setParam(3, 0, 0)
SteerR_6DoF.setParam(4, 0, 0)
SteerR_6DoF.setParam(5, steer, steer)
two things happen:
1) the steering is buggy. Although the property returns to zero after I let go off the key (I can see that in debug), the dummy continues to turn and the vehicle starts to jerk (this doesn't happen when I don't include that steer thing).
2) the whole game starts to lag until the framerate is really low.
I think that there is the same cause to the both bugs: every time the property steer changes the script is executed again. I think this means the script creates numerous constraints which cumulate up to the point the game starts to lag. Of course, it is then logical that once there is numerous constraints with various values of "steer", they would somehow collide and produce unsatisfactory results.
I have a basic idea how to relieve this: when steer property is changed, it would be better to destroy all constraints and recreate them with an updated value of steer. This could be a little jerky and wasteful (no need to destroy and recreate all the constraints).
What would be even better is to create a separate script which would only update already existing constraint (SteerL
-> AxleFL
and SteerR
-> AxleFR
) and attach this new script to the change sensor of the property steer.
My question is: how to do this? The separate script doesn't recognize SteerL_6DoF
and SteerR_6DoF
constraint and I don't know how to retrieve an existing constraint from an object.