Shutter door. Animate multiple simultaneous animations from a single file

I am trying to make a shutter door. this is a rendering from Blender of how it is supposed to work:
Shutter Door.

I used the animation template that comes with Castle Game Engine but when I run the animation it only runs one of the animations from the glb file:

function TViewMain.Press(const Event: TInputPressRelease): Boolean;

begin
  Result := inherited;
  if Result then Exit; // allow the ancestor to handle keys

      if Viewport1.TransformUnderMouse = Button then
      begin	  
{	  Port.PlayAnimation('Shutter.001', false);
     Port.PlayAnimation('Shutter.002', false);
     Port.PlayAnimation('Shutter.003', false);
     Port.PlayAnimation('Shutter.004', false);
     Port.PlayAnimation('Shutter.005', false);
     Port.PlayAnimation('Shutter.006', false);}

     Port.AnimationTimeSensor('Shutter.001').Start(true);
 
     Exit(true);
     
      end;

I have 6 individual animations in the .glb file. How do I run them all simultaneously?

The PlayAnimation method always runs a new animation, stopping the previous animation. (See docs at Castle Game Engine: CastleSceneCore: Class TCastleSceneCore ). This is deliberate, it allows PlayAnimation to e.g. perform cross-fading between old and new animation.

To play multiple animations simultaneously use the TTimeSensorNode.Start / TTimeSensorNode.Stop methods. You can get TTimeSensorNode instances that correspond to particular animations using e.g. TCastleSceneCore.AnimationTimeSensor method.

So in your case, simply change

  Port.PlayAnimation('Shutter.001', false);
  Port.PlayAnimation('Shutter.002', false);
  Port.PlayAnimation('Shutter.003', false);
  Port.PlayAnimation('Shutter.004', false);
  Port.PlayAnimation('Shutter.005', false);
  Port.PlayAnimation('Shutter.006', false);

to

  Port.AnimationTimeSensor('Shutter.001').Start(false, true);
  Port.AnimationTimeSensor('Shutter.002').Start(false, true);
  Port.AnimationTimeSensor('Shutter.003').Start(false, true);
  Port.AnimationTimeSensor('Shutter.004').Start(false, true);
  Port.AnimationTimeSensor('Shutter.005').Start(false, true);
  Port.AnimationTimeSensor('Shutter.006').Start(false, true);

Note: this assumes you’re sure that given animations exist. If this is not guaranteed, first check that Port.AnimationTimeSensor('xxx') <> nil.

Oh, and see example examples/animations/simultaneous_animations_one_scene ( castle-engine/examples/animations/simultaneous_animations_one_scene at master · castle-engine/castle-engine · GitHub ) for a simple demo of it.

why (false, true)?
when I change the code to what you suggested the if Viewport1.TransformUnderMouse = Button then has stopped working.

I’m going to correct the code I have.

See the API docs of TTimeSensorNode.Start:
https://castle-engine.io/apidoc/html/X3DNodes.TTimeSensorNode.html#Start-Boolean-Boolean-TFloatTime-

The first parameter false says whether to loop - I propose to set it as false since in your code sample, you also wanted to specify loop as false for PlayAnimation.

The second parameter says whether animation plays forward. true is the reasonable default :slight_smile:

Let me know if you have additional questions about this. To help with above, I’d need to see more code, and more information “how it stopped working” :slight_smile: