HPL3/SOMA/Modeling/Importing Animations

From Frictional Wiki
< HPL3‎ | SOMA‎ | Modeling
Jump to navigation Jump to search

Importing an animation registers an exported animation source on a SOMA entity so the clip can be previewed and played by name.

Before importing

Confirm that:

  • the entity already loads its intended animated mesh;
  • the exported animation uses the mesh's node or bone names;
  • the animation and mesh were exported with compatible scale and axis settings;
  • the animation file is in a directory included by the mod's resources.cfg; and
  • the source file has a unique, stable path inside the mod.

SOMA ships entity registrations that reference both .dae_anim and .fbx sources. This establishes support for those installed assets, not compatibility with every exporter version. Verify the chosen exporter with a minimal clip before producing a full animation set.

Add a clip to an entity

  1. Open the target .ent file in ModelEditor.exe.
  2. Enable Entity Preview from the lower toolbar.
  3. Open Edit Animations in the preview window.
  4. Choose Add new animation.
  5. Set a unique Name used by scripts and entity logic.
  6. Set File to the exported .dae_anim or .fbx source.
  7. Use Default for Layer unless the entity has a known layered setup.
  8. Begin with Speed set to 1.
  9. Save the entity and select the new animation in the preview controls.

The saved entity entry has this basic form:

<Animations>
    <Animation
        Name="open"
        File="entities/urban/toilet/shower_curtain/shower_curtain_open.fbx"
        Layer="Default"
        Speed="1"
    />
</Animations>

This example is taken from SOMA's shipped shower_curtain.ent. The animation's registered name is open; scripts play that name, not the filename.

Understand source and cache files

SOMA stores compiled animation data in .anm files. After deduplicating the paths referenced by shipped entity animation registrations:

  • 939 non-empty source paths are registered;
  • 879 corresponding source files are present in the installation;
  • 866 of those present sources have a same-stem .anm file;
  • 785 of those pairs use .dae_anim sources; and
  • 81 use .fbx sources.

For example:

ventilation_cluster_spin.dae_anim
ventilation_cluster_spin.anm

The source is the file registered on the entity. Treat .anm as generated engine data. When replacing a source animation, reload the entity and verify that the cache was refreshed rather than editing the cache manually.

Preview and validate

Use Entity Preview to check:

  • whether the animation appears in the selector;
  • whether it plays at the expected speed;
  • whether looping behaves correctly;
  • whether the skeleton moves without unexpected scaling or offsets;
  • whether the first and last poses meet correctly for a loop; and
  • whether physical bodies, sockets, and attached effects remain aligned.

The preview window can display the skeleton and physical objects and provides play, loop, step, time, and timeline controls.

SOMA's executable reports useful failures, including missing animation files, skeleton differences between the mesh and saved entity, vertices without a bone, vertices influenced by more than four bones, and missing transition animations.

Add events

Events are added to the registered animation in the Model Editor, not baked into the exported source file. Each shipped event record stores a name, time, type, destination socket, and value.

Available event types declared by SOMA include:

  • PlaySound
  • CreateParticle
  • Step
  • Message
  • PlayLoopSound
  • StopLoopSound

Add an event at the intended timeline position, choose its type, and provide the resource or socket required by that type. Test it in preview and in-game. A valid animation can still have a failing event if its sound, particle system, or destination socket is missing.

SOMA's robot_arm_welding.ent demonstrates timed loop sounds, ordinary sounds, particles attached to sockets, and a stop-loop event on one animation.

Add transitions

A transition registers a separate bridge clip to use when entering the selected animation from a previous animation.

  1. Register the base, target, and bridge clips as ordinary animations first.
  2. Confirm that each clip plays independently.
  3. Add a transition to the target animation.
  4. Set the previous animation and the bridge-animation name.
  5. Adjust the minimum and maximum previous-animation time only when the transition should be limited to a time window.
  6. Enable transition preview and test every route that can select the target animation.

SOMA's shipped entities contain 204 transition entries. The engine emits separate errors for a missing previous animation, missing transition animation, and missing transition base animation.

Test from script

After preview succeeds, place the entity in a test map and play the registered name:

Entity_PlayAnimation("Machine", "open", 0.1f, false, true, "OnAnimationFinished");

The SOMA API records the completion callback as:

void OnAnimationFinished(const tString &in asEntityName,
                         const tString &in asAnimName)
{
}

Use a loop only for a clip intended to repeat. Leave transition playback enabled only when the entity has a matching transition setup.

Troubleshooting

  • The file does not appear or load: verify the mod-relative path, extension, and resource configuration.
  • The animation name cannot be played: check the entity's registered Name; it can differ from the source filename.
  • The mesh deforms incorrectly: compare the mesh and animation hierarchy, node names, unit metadata, and export axes.
  • The entity reports a skeleton mismatch: reimport the mesh into the entity and confirm that the exported animation targets that same skeleton.
  • Events do not fire correctly: inspect event time, type, value, and socket separately from animation playback.
  • A transition fails: verify that the previous, target, and bridge names all match registered entity animations.
  • An update still plays old data: reload the entity after replacing the source and ensure the generated .anm cache is refreshed.

See also