Tap Through Animation Layers

Featured

Comments

8 comments

  • Avatar
    Zachery Grew

    Hi, would there be anyway to have each animation play its own sound?

  • Avatar
    Jonathan Solichin

    Hi Zachery!

    Yep! You would do something very similar. 

    First create an Audio component for each of your sound. In the objects panel: Add New -> Empty Object; then in Inspector panel: Add Component -> Audio. put your mp3 herein the Audio Track field. 

    You can pass these Audio components in via an array input like in the guide.

    // @input Component.AudioComponent[] audioComp

    Then when you tell the script to play animation in playAnimIndex, you can tell it  to play the AudioComponent as well.

     script.audioComp[index].play(1)

    Finally, we tell the sound to stop when we stop the animation in stopAnimIndex

    script.audioComp[index].stop(false)

    Let me know how it goes! Would love to see what you create :)

    Cheers,
    Jonathan

  • Avatar
    Wayne Rhodes

    I used the final script but Im getting any error 

    SyntaxError: empty expression not allowed (line 40)
    at [anon] (Hipster/Scripts/MultiAnim:40) internal

    Any idea what could be the problem?

  • Avatar
    Jonathan Solichin

    Hi Wayne, 

    Can you show us your script / line 40? This looks like a JavaScript error, but can't be sure without the code.

    Thanks in advance!

    Jon

  • Avatar
    Wayne Rhodes

    Problem fixed... missed the } off right at the end.

     

    All working but it brings me to another question. 

    All the animations look at the moment .

     

    Is it possible to keep the idle animation on loop until triggered with the tap and then play the other animation just once then revert back to idle?

  • Avatar
    Jonathan Solichin

    Glad to hear you found the issue :)

     

    You can take a look at Interactive Tap templates for an example of that. It's a template that's design to play an animation and then go back to the idle animation. 

    To have that in this script, something you can do is: instead of 

     script.animMixer.start(script.tapAnimLayer[index], 0, -1);

    You can use something like 

     script.animMixer.startWithCallback(script.tapAnimLayer[index], 0, 1, playIdle);

    where playIdle is a function that plays your idle animation. You can see more about this function here.

     

    Cheers!

    Jon

     

  • Avatar
    Wayne Rhodes

    Thanks Jon, 

    I replaced

    script.animMixer.start(script.tapAnimLayer[index], 0, -1); with
    script.animMixer.startWithCallback(script.tapAnimLayer[index], 0, 1, playIdle);

    so the script now reads as

    // -----JS CODE-----
    //@input Component.AnimationMixer animMixer
    //@input string[] tapAnimLayer
    // Starting animation index
    var currentAnimLayerIndex = 0;
    // Function runs at start of lens
    function onLensTurnOnEvent()
    {
    // start the new animation
    playAnimIndex(currentAnimLayerIndex);
    }
    var turnOnEvent = script.createEvent("TurnOnEvent");
    turnOnEvent.bind(onLensTurnOnEvent);
    function onTap(eventData)
    {
    // stop current animation
    stopAnimIndex(currentAnimLayerIndex);

    // increment current animation
    incrementAnimIndex();
    // start the new animation
    playAnimIndex(currentAnimLayerIndex);
    }
    var tapEvent = script.createEvent("TapEvent");
    tapEvent.bind(onTap);
    function incrementAnimIndex()
    {
    currentAnimLayerIndex = currentAnimLayerIndex + 1;
    currentAnimLayerIndex = currentAnimLayerIndex % script.tapAnimLayer.length;
    }
    function playAnimIndex(index)
    {
    script.animMixer.startWithCallback(script.tapAnimLayer[index], 0, 1, playIdle);
    script.animMixer.setWeight(script.tapAnimLayer[index], 1.0);
    }
    function stopAnimIndex(index)
    {
    script.animMixer.stop(script.tapAnimLayer[index]);
    script.animMixer.setWeight(script.tapAnimLayer[index], 0.0);


    and I get this error


    09:35:26 ReferenceError: identifier 'playIdle' undefined
    at playAnimIndex (Hipster/Scripts/MultiAnim:33)
    at onLensTurnOnEvent (Hipster/Scripts/MultiAnim:10) preventsyield

    Any idea what the problem is ? sorry I don't really have any coding knowledge

     

    Wayne

  • Avatar
    Jonathan Solichin

    Hi Wayne,

    Ah this error is because you haven't made a playIdle function.

    As mentioned above, playIdle should be a function you define to stop any current animation and play your idle animation. For example: 

    function playIdle() 
    {
    stopAnimIndex(currentAnimLayerIndex);
    script.animMixer.start(script.idleAnimLayer, 0, -1);
    script.animMixer.setWeight(script.idleAnimLayer, 1.0);
    }

    In this case we added a new variable to define our "idle" animation in the Inspector panel at the top of the file.

    // @input string idleAnimLayer

     

    We should also add a script to stop the idle animation similar to how we stopAnimIndex so that when we play a tap animation our idle animation will stop. 

    function stopIdle() 
    {
    script.animMixer.stop(script.idleAnimLayer);
    script.animMixer.setWeight(script.idleAnimLayer, 0.0);
    }

     

    Finally we can tell the script to use these new functions.

    When the lens start we want to play our idleAnimLayer instead of our tapAnimLayer

    function onLensTurnOnEvent()
    {
    // start the idle animation
    playIdle();
    }

    and when we tap we want to stop our idle animation as well. 

    function onTap(eventData)
    {
    // stop idle animation
    stopIdle();

    // stop current animation
    stopAnimIndex(currentAnimLayerIndex);

     

    So the overall lens script can look something like: 

    // @input Component.AnimationMixer animMixer
    // @input string idleAnimLayer
    // @input string[] tapAnimLayer
    // Starting animation index
    var currentAnimLayerIndex = 0;
    // Function runs at start of lens
    function onLensTurnOnEvent()
    {
    // start the idle animation
    playIdle();
    }
    var turnOnEvent = script.createEvent("TurnOnEvent");
    turnOnEvent.bind(onLensTurnOnEvent);

    function onTap(eventData)
    {
    // stop idle animation
    stopIdle();

    // stop current animation
    stopAnimIndex(currentAnimLayerIndex);

    // increment current animation
    incrementAnimIndex();

    // start the new animation
    playAnimIndex(currentAnimLayerIndex);
    }

    var tapEvent = script.createEvent("TapEvent");
    tapEvent.bind(onTap);
    function incrementAnimIndex()
    {
    currentAnimLayerIndex = currentAnimLayerIndex + 1;
    currentAnimLayerIndex = currentAnimLayerIndex % script.tapAnimLayer.length;
    }

    function playAnimIndex(index)
    {
    script.animMixer.startWithCallback(script.tapAnimLayer[index], 0, 1, playIdle);
    script.animMixer.setWeight(script.tapAnimLayer[index], 1.0);
    }

    function stopAnimIndex(index)
    {
    script.animMixer.stop(script.tapAnimLayer[index]);
    script.animMixer.setWeight(script.tapAnimLayer[index], 0.0);
    }

    function playIdle()
    {
    stopAnimIndex(currentAnimLayerIndex);
    script.animMixer.start(script.idleAnimLayer, 0, -1);
    script.animMixer.setWeight(script.idleAnimLayer, 1.0);
    }

    function stopIdle()
    {
    script.animMixer.stop(script.idleAnimLayer);
    script.animMixer.setWeight(script.idleAnimLayer, 0.0);
    }


    Let me know how it goes!

     

    Cheers,

    Jon

Please sign in to leave a comment.