Animating weepy character

Community Beginner ,
Sep 22, 2022 Sep 22, 2022

Copy link to clipboard

Copied

Hello,

 

I'm attempting to create a rig for an animated character and am running into a problem with an animated sequence in a time-remapped composition. It may be easier to explain using this recording:

 

 

Each facial feature has a one second in the composition. Appreciate any ideas. Thanks!

TOPICS
How to , Scripting

Views

60

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Sep 23, 2022 Sep 23, 2022

I think that would only make a slight difference:

s = effect("Eyebrow Tear")("Slider");
n = 0;
if (s.numKeys > 0){
  n = s.nearestKey(time).index;
  if (time < s.key(n).time) n--;
  if (n > 0){
    val = s.key(n).value;
  }else{
    val = s.key(1).value;
  }
}else{
  val = s.value;
}
if (n > 0){
  val + (time - s.key(n).time)%framesToTime(29);
}else{
  val;
}

Likes

Translate

Translate
Community Expert ,
Sep 22, 2022 Sep 22, 2022

Copy link to clipboard

Copied

You can probably do it, depending on how you're animating the slider. If you use a slider keyframe for each facial pose, then you could have a time remap expression that finds the most recent slider keyframe and just uses that value unless it's pose 6, in which case it uses 6 plus how long it's been since the keyframe (you'd probably need that to loop if it could be longer than the animation). In any case, quite do-able if you provide more detail.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 22, 2022 Sep 22, 2022

Copy link to clipboard

Copied

Let's see what I can provide.

 

The tears are indeed the 6th possible pose, though I can rearrange them. It runs for 29 frames before being intended to loop back to the first.

 

I have a time remap going for the tears sub-composition, but I haven't done anything with it yet. I could always make the tears a separate comp. It's more for convenience if I can make it work within the larger comp and selectable by the slider.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 22, 2022 Sep 22, 2022

Copy link to clipboard

Copied

It's hard to see enough detail in your video to catch the comp and layer names, but it appears that your tears subcomp is inside another comp (along with the other poses?), which is itself time remapped with an expression tied to your slider. That expression is where I would see this happening, but I don't have enough info to give you something you could just drop into that time remap property. However, it would look something like this:

s = effect("Eyebrow Tear")("Slider");
n = 0;
if (s.numKeys > 0){
  n = s.nearestKey(time).index;
  if (time < s.key(n).time) n--;
  if (n > 0){
    val = s.key(n).value;
  }else{
    val = s.key(1).value;
  }
}else{
  val = s.value;
}
if (val == 6 && n > 0){
  val + (time - s.key(n).time)%framesToTime(29);
}else{
  val;
}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

I appreciate the expression template. Sadly, I wasn't able to impliment it correctly but I also realize that I'm making this more complicated than necessary.

 

What if I added an expression to the time remap where the Slider's position (1 through 6) was the start point and the composition played for 29 frames before looping back to the same Slider point? That way, each expression would loop in blocks of 29 frames, which no one would notice unless the facial feature was likewise animated.

 

I'm not very strong at scripting so I can only imagine modifying the LoopOut expression.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

I think that would only make a slight difference:

s = effect("Eyebrow Tear")("Slider");
n = 0;
if (s.numKeys > 0){
  n = s.nearestKey(time).index;
  if (time < s.key(n).time) n--;
  if (n > 0){
    val = s.key(n).value;
  }else{
    val = s.key(1).value;
  }
}else{
  val = s.value;
}
if (n > 0){
  val + (time - s.key(n).time)%framesToTime(29);
}else{
  val;
}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

We're close but not quite there. The new expression works for the sliding control aspect but the tears are still fixed.

 

Hopefully this newer screenshot is easier to read.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

The expression will really only work if the slider has keyframes.

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

This might work without keyframes:

s = effect("Eyebrow Near")("Slider");
n = 0;
if (s.numKeys > 0){
  n = s.nearestKey(time).index;
  if (time < s.key(n).time) n--;
  if (n > 0){
    val = s.key(n).value;
  }else{
    val = s.key(1).value;
  }
}else{
  val = s.value;
}
if (n > 0){
  val + (time - s.key(n).time)%framesToTime(29);
}else{
  val + time%framesToTime(29);
}

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Beginner ,
Sep 23, 2022 Sep 23, 2022

Copy link to clipboard

Copied

LATEST

Oh wow! I didn't realize about the keyframes. Works great as soon as I added them. Further proof I need to learn about expressions and coding.

 

I'll give the other script a go as well but this solves my challenge either way. Thank you!

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines