I’m having a bit of a problem here.
For my ship system, I want the engine’s position to be used as a vector generator.
So the position, orientation of the engines form the vector and the power the vector’s magnitude.
Then the vector should be applied to the ship the main parent. The problem is the I’m using applyForce, or setLinearVelocity, where the tuple or list is an x,y,z values, and takes orientation and position of the vector into account.
My idea was to do something like that:
if whatnot:
ldir= LeftEngine(power * energy,(LeftEngine.position)*LeftEngineOrientation)
ship.applyForce(ldir,1)
but although I haven’t test it, I’m sure I’ll get a " one of the values was not a float" error, so…
Any ideas?
this message appears if you provide an incorrect value. E.g. a string, a list or something else. Without the definition of LeftEngine we can’t give you an advice.
applyImpulse() was my first thought as well. Be careful it does not what the docs suggest. You can have a look at my buoyancy library. It uses applyForce (to apply the upward force). You might want to see how it is done there.
Another option are: connect other game objects via rigid body joint to the ship. Then you can apply forces to this “engines”. They will transfer the forces to the connected models of the ship. Make sure you create a well balanced model.
I created an helicopter with that method. It works pretty well.
Thank you Monster!
See, I don’t want a lot of physics working on a ship. It will have rich handling with the console and the engine’s room doing their things (mostly transferring power and activating options). Having dynamic or rigid engines could be a bit of a hassle, specially when it comes to upgrade. These parts will come packed and unfold when parented to the ship. Some engines will be moving parts, so I need as less physics calculations as possible.
Haha, wow, my mistake! I have the Blender docs downloaded and linked in my browser’s favorites bar.
I fixed the link.
EDIT: @Torakunsama - Also, be aware of how to use applyImpulse. I used it for my 7DFPS project, and I found that the first position value is relative to the object you’re applying the impulse on, so if you just want to apply a movement to the object’s center point with a force from the engine (relative to the engine’s orientation), then I believe you should use [0, 0, 0]. To make it relative to the engine’s position on the ship (like if it were on the wing, then it would spin the ship around), you should probably get the difference from the ship to the wing, and use a ‘backward’ force. I’m not quite sure, though.
Yes, applyImpulse has the (point, force) combination, but it’s not like linear velocity. To be easier to handle, I need my ships or the engines to have a speed limit. So it would be nice if I did’t have to limit the speed with conditions… in any case, it works great. I just need to make it work with the mouse and flight mode.
In stationary, the ship will counteract the effect of gravity and apply the impulse on one or other engine according to the orientation. I could as well calculate the vector required and set it as the force, then adjust the engines orientation, but it all goes to the same. The ship has 2 main engines and 2 auxiliary thrusters(for pitch?).
In normal flight, the thrusters help keep altitude and the main engines do the steering. So if the mouse moves to the right, I need the left engine to increase it’s output, and vice versa. The power transferred to the engines is relative to the generators output and how many systems will be installed in the ship. For example, for maximum power in the engines, a ship must be run manually and the pilot must suit up.
The purpose of this is that engine assembly, type and generators power and configuration can change the way a ship behaves. I’ll deal with the settings later on!
def steer(cont):
#print("steering")
own= cont.owner
x, y = bge.logic.mouse.position
x -= 0.2
y -= 0.2
if not "init" in own:
own["init"] = 1
x, y = 0.0, 0.0
#keyb= cont.sensor['steering']
EngineRoom= [r for r in own.children if "Engines" in r]
#print(EngineRoom)
engines= [ER.children for ER in EngineRoom]
#print(engines)
for engine in engines:
if "L" in engine:
print(engine)
LEngine= engine
if abs(x) > 0.005 :
ldir=LEngine.worldPosition
own.applyImpulse(ldir,mathutils.Vector(0,(LEngine["Power"]*own["LE_energy"]*-x),0)*LEngine.worldOrientation); print("powering L engine")
if "R" in engine:
REngine= engine
if abs(x) > 0.005 :
rdir=REngine.worldPosition
own.applyImpulse(rdir,mathutils.Vector(0,(REngine["Power"]*own["RE_energy"]*-x),0)*REngine.worldOrientation)
if "U" in engine:
UEngine= engine
if abs(x) > 0.005 :
udir=UEngine.worldPosition
own.applyImpulse(udir,mathutils.Vector(0,(UEngine["Power"]*own["UE_energy"]*-x),0)*UEngine.worldOrientation)
if "D" in engine:
DEngine= engine
if abs(x) > 0.005 :
ddir=DEngine.worldPosition
own.applyImpulse(ddir,mathutils.Vector(0,(DEngine["Power"]*own["DE_energy"]*-x),0)*DEngine.worldOrientation)
bge.logic.mouse.position = (0.2,0.2)
Just some refactoring. If I haven’t done something wrong it should exactly do what your above script does. I do not have the option to test it.
Edit: updated version
def steer(cont):
own= cont.owner
x, y = bge.logic.mouse.position
x -= 0.2
y -= 0.2
if not "init" in own:
own["init"] = 1
x, y = 0.0, 0.0
#keyb= cont.sensor['steering']
EngineRoom= [r for r in own.children if "Engines" in r]
#print(EngineRoom)
engines= [ER.children for ER in EngineRoom]
for engines in engines:
runEngines(ship, engines, x)
def runEngines(ship, engines, x):
if "engines" not in engines:
return
engines= part.children
for engine in engines:
runEngine(ship, engine, x)
def runEngine(ship, engine, x):
if abs(x) <= 0.005:
return
if "L" in engine:
applyForce(ship, engine, "LE_energy")
if "R" in engine:
applyForce(ship, engine, "RE_energy")
if "U" in engine:
applyForce(ship, engine, "UE_energy")
if "D" in engine:
applyForce(ship, engine, "DE_energy")
def applyForce(obj, engine, shipEnergyProperty):
yForce = engine["Power"]*ship[shipEnergyProperty]*-x
force = mathutils.Vector(0,yForce, 0)*engine.worldOrientation
obj.applyImpulse(engine.worldPosition, force)
It’s weird, I can’t detect the engines.
I can access them with engines.children, but then cant access by name or property.
When I go: if “L” in engine: print (engine) or if “L_” in engine.name: print(engine), nothing happens…
what’s happening?
Thank you Monster!
I manage to simplify and make it work! It was a problem with local variabes. The engineRoom and the engines variable. Engines was not a list of all engines but most likely the last object…
Now need to stabilize the ship’s handling. Be back soon!
Edit:
The applyImpulse function works in global space? This makes powering individual engines useless!
Will have to resort to vectors, I think!
It really doesn’t work, I only got a few days left to solve this problem, maybe I’ll have to resort to other kind of force, maybe collision?
Animation will require mostly no code.
Will have to go with that for now! The problem will be activating the actuators with the mouse movement.