7 Replies Latest reply on Dec 29, 2011 1:22 AM by MichaelDavis57

    Expression joy - if/else




      Expressions are really really fun aren't they?

      I've got a fiddly one to write, which I imagine is pretty basic for a seasoned AE pro, which unfortunately I am not.


      I'm animating a face, which 'talks' when sync'd up with an audio layer.  The audio sync I've sorted, works using time remapping to switch between one of five different heads, because they have different stages of mouth open-ness.

      The problem I'm having, is that I want the position of the eyes to move slightly, depending on the mouth, so they appear to stay in position on the head (i.e. they nudge up if the mouth is open wider).


      Seems the easiest way to do this is with if/else expressions, but I can't get it to work properly.  I'm probably just using the wrong terms of brackets or something.

      I've set up a test in the eye layer position field to get the syntax right, as below:


      a = thisComp.layer("BTstraightheads").timeRemap;

      if(a > 2 ) { [1800 , 400];

      }else{ [200 , 400];}


      The "a" part is the time-remapped mouth, so that varies between 1 to 5.  The way I see it, it should be on the right of the screen if the remapped value is 3, 4 or 5, and left of the screen if 1 or 2. (it's an HD comp, so 1920x1080)

      But if just sits on the left, irrespective of the value.  I've tried putting in 'if value(a>2)', and that makes it sit permanently on the right.


      Can anyone help with this?  I'd be really grateful.




        • 1. Re: Expression joy - if/else
          MichaelDavis57 Level 1

          RIght, I've kind of figured out why it wasn't moving.  By linking the remap values to a null, turns out they were bubbling away at some tiny tiny value, not the actual frame number, so that's useless.



          Does anyone know a way to tell an expression to search for a range of values in an 'if' condition?

          Meaning type in something like:


          if (5<a<7) { [1800,400];

          } if (7<a<10) [1600,400];


          etc etc.  Basically I need discrete options for the position, so it sits at either point 1, 2 or 3, based on a range of continuous values.  Essentially an "if / and" qualifier.


          Any way AE can do that?



          • 2. Re: Expression joy - if/else
            Rick Gerard Adobe Community Professional & MVP

            This question may end up being moved to After Effects Expressions. That's the best place to post questions about expressions.


            Your biggest problem is that you're assuming that the Time Remap values will return frames. Linking to a null has nothing to do with the problem. Mouth open at frame 5 for example in an NTSC comp returns a value of .166833 instead of 5. You need to first convert time to frames. Do that by dividing the time by the frame duration.


            t = thisComp.layer("BTstraightheads").timeRemap; // time
            a = t/thisComp.frameDuration // time to frames


            Now your expression should work. However, your eyes won't move slightly, they will move from 1600 pixels unless you missed a zero in your expression (1800 to 200). The way you have the expression written the eyes will snap into position.


            I've got another little problem with the way you've written the expression. I'd add a value rather than define one. That let's you position the elements manually and even add keyframes if you like. Change


            if(a > 2 ) { [1800 , 400];
            }else{ [200 , 400];}


            to this:


            if(a > 2 ) { 
                 np = [0 , 0]
                 np = [200 , 0]
            value + np


            You also don't need the semicolons in your if/else statement and things are a lot easier to read if you give a little blank space to the expression.


            A smoother, and easier way to write the expression would be to simply multiply the a value (I'd call it np for new position) by a number that would give you the max new position and add that to the value of the current x position. The resulting expression is very simple. It looks like this. No if, else necessary and it's easier by far than writing in an ease function.


            t = thisComp.layer("BTstraightheads").timeRemap;
            a = t/thisComp.frameDuration;
            value + a * 20


            This will move the layer 100 pixels to the right if your max time remap value is 5. You could also use an array in the last line if you like to keep things clearer in your mind. that would look like this: value + [a * 20, 0]

            1 person found this helpful
            • 3. Re: Expression joy - if/else
              MichaelDavis57 Level 1

              Thanks Rick, that does make it ping into life.


              The issue I'm having, that I didn't anticipate, is that I thought I could take the time remap value (which appears as frame 0, 1, 2, 3 or 4) and assign an outcome (i.e. a position) for each of those values.

              But the remapped value is actually, like you say, time, and fluctuates continuously, even when turned to frames as above.  At points the eye is gliding across a static face.


              Do you know if there's an expression format to get AE to select bands, eg values between 5 and 7, and then have multiple 'if' statements?

              Listing if a>4..., if a>3..., if a>2 etc doesn't seem like an option.


              Really appreciate your help.

              • 4. Re: Expression joy - if/else
                Rick Gerard Adobe Community Professional & MVP

                If you want to go to specific positions for specific values then you can stack up the if statements. Converting time to frames gives you whole numbers only when the layer is running in real time. Since you're time remapping you'll need to use the Java math Math.round function.


                Say you wanted to move 10 pixels right if 1, 15 if 2, 20 if 3 and 25 if 4  with a maximum movement of 30 your expression would look like this:


                t = thisComp.layer("BTstraightheads").timeRemap; // 
                a = Math.round(t/thisComp.frameDuration) // time to frames
                if(a <= 1 ) { 
                     np = [0 , 0]
                else if (a <= 1 ) { 
                     np = [10 , 0]
                else if (a <= 2 ) { 
                     np = [15 , 0]
                else if (a <= 3 ) { 
                     np = [20 , 0]
                else if (a <= 4 ) { 
                     np = [25 , 0]
                else if (a >= 5 ) { 
                     np = [30 , 0]
                 value + np


                I hope this helps.

                • 5. Re: Expression joy - if/else
                  MichaelDavis57 Level 1

                  That's absolutely brillant, thanks.

                  • 6. Re: Expression joy - if/else
                    Rick Gerard Adobe Community Professional & MVP

                    Except the second if through the last should be increased by 1. If 1 and if 2 are equal. 

                    • 7. Re: Expression joy - if/else
                      MichaelDavis57 Level 1

                      Thanks again, Rick.

                      I've pulled out the linear function that was (needlessly) giving sound-sync values from audio, and in fact anything depending on time remapping values, and just replaced everything with a tweaked version of your else if equation.

                      Now everything is working off the same values from the audio keyframes, works a charm.