Space Engineers

Space Engineers

Not enough ratings
uhiANIM 2.1.4 Configuration Guide
By jezor
The powerhorse behind the Animatronics Division, the uhiANIM script is capable of animating even the most complex movements.
   
Award
Favorite
Favorited
Unfavorite
See it in action
Recording
The script provides a functionality to record the animation, one Animation Mode at a time.

It is activated by running the Programmable Block with the RECORD argument:
RECORD;AnimationSegmentName;AnimationModeName
Once the recording mode is activated, the animation execution will be paused.

Now you can move parts manually to desired positions, and run the Programmable Block with the RECORD_STEPS argument. Note this will only record values for parts whose values have changed since the recording started.

Both angle / position and velocity is recorded, while the precision is set to 0.1. You may later tweak these values manually in the CustomData.

You may run RECORD_STEPS multiple times if the animation consists of more than one movement.

Finally, once you are satisfied with the recording, run the Programmable Block with the RECORDING_DONE argument. All recorded steps will be saved in the CustomData of your Programmable Block.

Note that each recording will override values for the Animation Mode, so if you'd like to save a previous value, you must do so manually.
Configuration
The animations are configured with CustomData in INI format.

Complex animations
Script will automatically use it's own Programmable Block's CustomData, but if your animation is too complex to fit it (not sure what the limitation is), you may divide configuration among other blocks and specify their names with:
[animation] definitions= |Some Block |Some Other Block
Output handling
By default, script's output is printed to Programmable Block's display. You may specify the LCD panel to which the script will output data with the infoSurface parameter:
[animation] infoSurface=My Informative LCD
Ship controller block
You can define which seat / cockpit / remote control block will be used to control the animation with the controller configuration parameter. By default, the main cockpit of the grid the programmable block has been placed on will be preferred. If not found, a random block will be used.
[animation] controller=Pilot Seat
Controller deadzone
If you are using a controller, the inputs may register even when no buttons are pressed. To counteract this, use the controllerDeadzone parameter. It must have a value between 0 and 100 and is set to 10 by default.
[animation] controllerDeadzone=25
Deadzone is calculated as a percentage of the input value.
Controller sensitivity
Input-based triggers (CONTROLLER_*) depend on the input sensitivity. Unfortunately, I couldn't find any reasonable way to fetch sensitivity values. The documentation[github.com] is very vague on the topic.
Directional input from user/autopilot. Values can be very large with high controller sensitivity
If anyone knows a better way to handle this, please let me know in the comments.

For now, these may need to be manually adjusted if you are not playing on PC. The following are the default values:
[animation] moveSensitivity.X=1 moveSensitivity.Y=1 moveSensitivity.Z=1 rotationSensitivity.X=9 rotationSensitivity.Y=9 rollSensitivity=1

You can also enable automatic sensitivity detection with the autoSensitivity parameter. This is very expensive, as it overwrites the animation configuration and you should disable it once all sensitivity values are detected:
[animation] autoSensitivity=true
Animation Segments
Animation is divided into Segments, which represent different movable parts of your blueprint. For example, you may want to define a separate Segment for animating legs, and another for animating arms. Animation Segments should be independent from each other, as they are executed in parallel.
Animation Modes
Each Animation Segment may have one or more Animation Modes, which are used to describe a particular action. For example, "legs" Segment may use modes such as "moveForward" or "jump". Only one Animation Mode may be active per Animation Segment at any given time.

An Animation Mode consists of one or more Animation Steps, which describe movement of a singular mechanical part. For example, you may include a step to "move knee joint to 30° at 3RPM".
Animation Mode Triggers
Animation Modes are triggered by either a TRIGGER Animation Step or one of the following triggers:
  • NONE - never triggers, may be used to temporarily disable a particular Animation Mode
  • ARGUMENT_<custom_argument> - triggers the script is executed with custom_argument
  • CONTROLLER_NO_INPUT - triggers when player does not press any buttons
  • CONTROLLER_FORWARD - triggers when player presses e.g. "W" while sitting in a cockpit
  • CONTROLLER_BACKWARD - triggers when player presses e.g. "S" while sitting in a cockpit
  • CONTROLLER_NEITHER_FORWARD_NOR_BACKWARD - triggers when player does not press either "W" or "S"
  • CONTROLLER_LEFT - triggers when player presses e.g. "A" while sitting in a cockpit
  • CONTROLLER_RIGHT - triggers when player presses e.g. "D" while sitting in a cockpit
  • CONTROLLER_NEITHER_LEFT_NOR_RIGHT - triggers when player does not press either "A" or "D"
  • CONTROLLER_UP - triggers when player presses e.g. "SPACE" while sitting in a cockpit
  • CONTROLLER_DOWN - triggers when player presses e.g. "C" while sitting in a cockpit
  • CONTROLLER_NEITHER_UP_NOR_DOWN - triggers when player does not press either "SPACE" or "C"
  • CONTROLLER_ROLL_CLOCKWISE - triggers when player presses e.g. "E" while sitting in a cockpit
  • CONTROLLER_ROLL_COUNTERCLOCKWISE - triggers when player presses e.g. "Q" while sitting in a cockpit
  • CONTROLLER_NO_ROLL - triggers when player does not press either "E" or "Q"
  • CONTROLLER_PITCH_UP - triggers when player moves mouse upwards while sitting in a cockpit
  • CONTROLLER_PITCH_DOWN - triggers when player moves mouse downwards while sitting in a cockpit
  • CONTROLLER_NO_PITCH - triggers when player does not move mouse either downwards or upwards
  • CONTROLLER_ROTATE_LEFT - triggers when player moves mouse to the left while sitting in a cockpit
  • CONTROLLER_ROTATE_RIGHT - triggers when player moves mouse to the right while sitting in a cockpit
  • CONTROLLER_NO_ROTATION - triggers when player does not move mouse either to the left or right

If multiple triggers are specified, the animation mode will only be executed if all of the triggers are active.

Additionally, an Animation Mode may be set to repeat or stop after all steps finish executing.
Lazy Animation Mode
Animation Mode may be marked as lazy, which means it will only be initialized when it's actually executing.
This is an expensive operation and should be reserved only for Animation Modes that are either very complex, very rarely used or only included by other Animation Modes. The animation setup complexity is shown in the console log of programmable block - if the value is close to 100%, you should probably make some Animation Modes as lazy (when the value exceeds 100%, the script will fail to run). Likewise, the animation peak runtime complexity is displayed on the info LCD - it's best to ensure the value of it stays as low as possible.
[someRarelyExecutedSegment.someLazyMode] triggers=CONTROLLER_DOWN lazy=true steps=TOGGLE;BLOCK;Test;true
By default, Animation modes are not lazy.
Animation Mode Priority
The priority field within an Animation Mode decides which mode will be chosen if triggers for multiple modes are active. For example:
[priority.1] triggers=CONTROLLER_BACKWARD priority=1 steps=TOGGLE;BLOCK;Test;true [priority.3] triggers=CONTROLLER_RIGHT priority=3 steps=TOGGLE;BLOCK;Test;true
If both "S" and "D" keys are pressed, the priority.3 Animation Mode will be triggered.

By default, the priority of all modes is set to zero.

If two Animation Modes have the same priority, one Animation Mode will be preferred but this preference is completely arbitrary. What this means is, one Animation Mode will be consistently preferred but there is no guarantee which one.
Animation Mode Variables
You may define any number of custom variables for your Animation Mode. These variables may then be used anywhere within the Animation Mode with string interpolation syntax, e.g. ${MY_VARIABLE}.
[legs.jumpOnOneLeg] variables= |JUMP_TRIGGERS=CONTROLLER_UP,CONTROLLER_DOWN |JUMP_PRIORITY=123 |REPEAT_JUMP=false |LEG_SIDE=Left |PRECISION_AND_SPEED=0.5;3 triggers=${JUMP_TRIGGERS} repeat=${REPEAT_JUMP} priority=${JUMP_PRIORITY} steps= |MOVE;BLOCK;${LEG_SIDE} Leg Knee Joint;45;${PRECISION_AND_SPEED};CONTINUE |MOVE;BLOCK;${LEG_SIDE} Leg Foot Joint;25;${PRECISION_AND_SPEED};WAIT
Animation Step Types
uhiANIM provides four types of Animation Steps: MOVE, TOGGLE, LOCK and TRIGGER. Each Animation Mode may use any combination of these.
⠀⠀MOVE
Consists of the following parts, separated by a semicolon:
  • block search type - BLOCK (looks up target block by exact name), BLOCKS (looks up multiple blocks that contain given name) or GROUP (looks up blocks by exact group name)
  • block search name - string that will be used to query the target blocks
  • target angle - for rotors and hinges it is the angle to which they should move, for pistons it is the positions to which they should extend or retract
  • precision - only applicable to WAIT condition, the animation will not proceed until the step is completed within given precision offset (e.g. if precision is set to 1° and target angle is set to 10°, the step is considered completed when an angle greater than 9° or lower than 11° is reached)
  • velocity - the speed at which the part will move (in RPM, actual speed may differ depending on the difference between current and target angle)
  • wait condition - either CONTINUE (next step will be executed immediately after this step) or WAIT (next step will be executed only after this step is completed)
Example
|MOVE;BLOCK;Some Block;45;0.5;3;WAIT
Will move a single block with name "Some Block" to 45° at 3RPM and will wait until the angle reaches between 2.5° and 3.5°.
⠀⠀SHIFT
Allows translating direct controller input to block movement (similar to ordinary rotation with gyroscopes):
  • block search type - BLOCK (looks up target block by exact name), BLOCKS (looks up multiple blocks that contain given name) or GROUP (looks up blocks by exact group name)
  • block search name - string that will be used to query the target blocks
  • trigger - trigger value used to determine if the step has completed (see "Animation Mode Triggers" section)
  • minimum value - similar to target angle in the MOVE step, except here it determines the lower limit of motion range
  • maximum value - similar to target angle in the MOVE step, except here it determines the upper limit of motion range
  • velocity - same as velocity in the MOVE step, except the sign of the value matters (negative values will move the component towards the lower limit, and positive values will move the component towards the upper limit)
  • velocity depends on input - when set to true, the velocity will be scaled based on input sensitivity; when set to false, velocity will be constant
Example
[torsoRotation.left] triggers=CONTROLLER_ROTATE_LEFT repeat=false steps=SHIFT;BLOCK;Torso Rotor;CONTROLLER_ROTATE_LEFT;-45;45;-20;true [torsoRotation.right] triggers=CONTROLLER_ROTATE_RIGHT repeat=false steps=SHIFT;BLOCK;Torso Rotor;CONTROLLER_ROTATE_RIGHT;-45;45;20;true
Will allow the block Torso Rotor to move towards -45° at 20RPM as long as the player continues to press "A", and towards 45° at 20RPM as long as the player continues to press "D".
⠀⠀TOGGLE
May be used to enable or disable components:
  • block search type - same as above
  • block search name - same as above
  • should be enabled - true / false
Example
|TOGGLE;BLOCKS;Hazard Light;false
Will disable all blocks with name containing "Hazard Light".
⠀⠀LOCK
Allows locking / unlocking landing gears and magnetic plates:
  • block search type - same as above
  • block search name - same as above
  • should lock - true / false
  • wait condition - same as above; if blocks are to be locked, WAIT will pause the animation until any of the blocks are in locked status, if blocks are to be unlocked it will pause until all of the blocks are in unlocked status
Example
|LOCK;GROUP;Legs Magnetic Plates;true;WAIT
Will lock all blocks within a group named "Legs Magnetic Plates".
⠀⠀TRIGGER
Allows triggering another Animation Mode:
  • segment name - name of the target Animation Segment
  • mode name - name of the Animation Mode to be triggered
Example
|TRIGGER;legs;jump
Will trigger the "jump" Animation Mode of the "legs" Animation Segment.
⠀⠀INCLUDE
Used for creating modular Animation Modes. This step will copy all steps from specified Animation Mode into the Animation Mode it is called from. The arguments are:
  • segment name - name of the target Animation Segment
  • mode name - name of the Animation Mode to be included
  • ...variables - key-value pairs of variables to be overridden in the target Animation Mode
Example
[legs.straightenAll] triggers=CONTROLLER_UP repeat=false steps= |INCLUDE;legs;straightenOne;LEG_SIDE=Left |INCLUDE;legs;straightenOne;LEG_SIDE=Right |INCLUDE;legs;straightenOne;LEG_SIDE=Left;CONTINUITY=WAIT |INCLUDE;legs;straightenOne;LEG_SIDE=Right;CONTINUITY=WAIT [legs.straightenOne] triggers=NONE variables= |LEG_SIDE=Neither |CONTINUITY=CONTINUE steps= |MOVE;BLOCK;${LEG_SIDE} Leg Joint;0;0.5;3;${CONTINUITY}
When the player presses the "SPACE" key, both legs will be straightened and the animation will be paused until they are both straight.

Note the INCLUDE step only cares about steps, and does not copy any other configuration of the target Animation Mode.
Circular inclusion
Animation Modes must not reference each other. If they do, the animation setup will fail. For example:
[exampleSegment.referenceEnd] steps=INCLUDE;exampleSegment;referenceStart [exampleSegment.referenceStart] steps=INCLUDE;exampleSegment;referenceChain [exampleSegment.referenceChain] steps=INCLUDE;exampleSegment;referenceEnd
The circular inclusion of referenceStartreferenceChainreferenceEndreferenceStart will break the animation and throw the following exception:
“circular inclusion is not allowed; started from exampleSegment.referenceStart (step INCLUDE;exampleSegment;referenceChain)”
⠀⠀COMMENT
If the first character in the step definition is a dash -, the entire line will be treated as a comment and ignored in its entirety. This allows for visual separation of steps, e.g. to signify what s collection of steps is responsible for.
Example
|-This is a comment |------This is also a comment
Example
[body.dance] triggers = CONTROLLER_FORWARD repeat = true steps = |------ SHOW ME THEM MOVES |LOCK;BLOCKS;Magnetic Plate;false;CONTINUE |MOVE;BLOCK;Right Leg Joint;10;0.5;5;WAIT |MOVE;BLOCK;Left Leg Joint;40;0.5;3;CONTINUE

Here we define a singular Animation Segment named "body" with one Animation Mode named "dance".
It will be triggered when player presses "W" and will repeat until another Animation Mode is triggered.
On each repeat, it will execute the following actions:
  1. unlock all blocks with name containing "Magnetic Plate"
  2. move block with name "Right Leg Joint" to 10° at 5RPM and pause animation until it is within 0.5° of that angle
  3. move block with name "Left Leg Joint" to 40° at 3RPM
  4. repeat from step #1

You can find a more elaborate animation example by subscribing to the Animatronics Division's mech, Polly.
Limitations
Forced rotation direction
The script automatically calculates which way the block should rotate to arrive at the target angle. It may or may not work if you set the target angle at over 360 or under 0 for a rotor.
Similar scripts
MECS (Motor Extensible Control Sequencer, workshop, guide) - same concept, but much different implementation.

BTWC Advanced Walker Script (workshop) - specialized for automating mechs. Likely much easier to use if this is what you are aiming for, but also more limited.