Hi everyone, I've noticed a lot of people have trouble understanding these three functions (abbreviated AF, AOF, and AAF for this tutorial) and these are the three most used functions in pretty much all of my contraptions, so I thought I'd try to show how to use them. I tried making a video tutorial but I ramble on a lot so it ended up being 15 minutes or so :S
First I'll lay out the abbreviations that I'll use in the tutorial. I think they're pretty self explanatory for the most part. And on most of the force (NOT THE POSITION OF AOF) arguments in these functions, you're probably going to want a multiplier. Just mess with the multipliers a bit to get the behavior you want. If you're using just a simple E2 gate, you're probably going to want to go with a fairly small multiplier - maybe 2/100,3/100,4/100, something like that. Experiment a lot with it
Code:
E = entity() # Or you can use something like E = entity():isWeldedTo() or import your own entity as an input
Pos = E:pos()
Vel = E:vel()
Ang = E:angles()
AngVel = E:angVel()
Forward = E:forward(),Right= E:right(), Up = E:up()
Inertia=shiftL(ang(E:inertia()))
Mass = E:mass()
AF is basically a vector thruster located at the props location (you can see this using the "picker" add on). It takes one vector argument and can only cause translational (side to side, up and down, and forward/back) movement. My most common use for this is to act as a force to slow the prop down,
This applies force in the opposite direction that the entity is moving, causing it to slow down.
Another use for AF is to go to one specific point. If you want to go to point A,
Code:
V = A-Pos
V /= V:length()
E:applyForce((V-Vel)*Mass)
This code applies force on all axis proportional to the difference - if you're 500 units away on the x axis, it will apply 500 units of force, then when you're at 250 it will apply 250 units, etc. I also added in friction force from the earlier code which allows it to actually work well. The Mass multiplier aids in moving the prop by taking the props mass into account - it takes more force to move a prop weighing 1000 than a prop weighing 1. Note that if you are simply using this on a normal e2 model, it will be equal to 1, so it's not needed.
Next is applyOffsetForce. This is similar to AF, but you can apply the force at any point on the map and it will be like you welded a vector thruster at that point to the e2/entity. Note that this is in global coordinates - that is,
Code:
E:applyOffsetForce(U,Pos)
#is the same thing as
E:applyForce(U)
A common use for this is make a prop face any coordinate (and doesn't spaz out at any particular orientation)
If you wanted the FRONT of the contraption to face TP (if you use picker2, front is the direction from the origin going out on the red/x axis)
Code:
V = TarP-Pos
E:applyOffsetForce(V,Pos+Forward)
E:applyOffsetForce(-V,Pos-Forward)
This works similarly to the example about going to a specific point only it does it twice, away from the center (so it causes rotation), and negates any translational movement. You'll also want to add the angular friction code that comes later to smooth out the movement.
Last but not least is the applyAngularForce function. It does exactly what it says - applies angular force.
Heres code that balances something (pitch = 0, roll = 0)
Code:
E:applyAngForce((-Ang:setYaw(0) - AngVel)*Inertia)
The Inertia multiplier accounts for the different inertia values on the different axis, allowing you to rotate the prop more easily and more efficiently.
The setYaw makes the yaw = 0; this is so that it doesn't try to be at that bearing, yaw = 0, all the time. Also, the kind of equation I'm using for this is
Code:
NewVal = TarVal - CurVal - $CurVal
TarVal is 0, CurVal is Ang:setYaw(0), and $CurVal is AngVel
To simply have angular friction, only include the -AngVel (you can use this on the point-to code earlier)
Here's some code that makes the E2 hover at z = 100. It resists movement and snaps to pitch = 0 and roll = 0 pretty quickly.
Code:
@name e2hover
@inputs
@outputs
@persist
@trigger all
runOnTick(1)
E = entity() Pos = E:pos()
Ang = E:angles() AVel = E:angVel()
Vel = E:vel()
Inertia = shiftL(E:inertia():toAngle())
TarZ = 100
AngF = -(Ang:setYaw(0)*20 + AVel)*5/100
E:applyAngForce(AngF)
Vec = (TarZ - Pos:z())*vec(0,0,1)*10
E:applyForce(Vec - Vel)
I think that's about it! Constructive criticisms, corrections, etc are very welcome! And please go easy on me, this is my first time ever writing a tutorial for anything. I hope you enjoy it and learn from it
Bookmarks