Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Animator.Play() Not Playing with "Cull Completely" and SkinnedMeshRenderer "isVisible"

Discussion in 'Animation' started by cassius, Mar 21, 2022.

  1. cassius

    cassius

    Joined:
    Aug 5, 2012
    Posts:
    124
    I'm trying to optimize some of my character animations. To do that, I've switched their animators to Cull Completely and immediately noticed that some of the animations won't play unless I choose either "Always Animate" or "Cull Update Transforms". I'd prefer to stick with Cull Completely since I don't need to continue off-screen animations at all.

    My scenario is like this.
    • Animated character checks every 1.5s if it's within 50 units of the camera and the character is on-screen the entire time.
    • If within 50 units, check that SkinnedMeshRenderer.isVisible.
    • If that's true, do an animator.Play("animation_name", -1, 0.0f)
    I know with 100% certainty the final conditional gets met as I set a boolean to true in the conditional which is set nowhere else. I know with 100% certainty that the animation clip referenced is ok because if I switch to either "Cull Update Transforms" or "Always Animate", everything works just fine, albeit less performant. However with "Cull Completely" it doesn't play the animation at all, and when I check the state of the Animator it shows the Entry clip as playing - which itself is very unexpected. (Side note: This is very strange because the Entry clip is almost always bypassed with another clip starting well before any of the conditions above even happen, and no simple way to get back to the Entry animation) Well, more specifically, the Entry clip is the current clip but appears paused or inactive at the first frame.

    Documentation for Culling Modes is fairly slim, so I'm not sure what I'm missing or if this is a bug?

    Unity 2019.4.29.

    Edit: One other thing of note. If I rotate the camera away from the character and immediately turn it back to bring them into view, the correct animation does play as though it was playing all along (I don't need to start the animation, it's magically already playing). So I'm guessing this has something to do with the inner workings of the Animator but I don't know what.
     
    Last edited: Mar 21, 2022
  2. cassius

    cassius

    Joined:
    Aug 5, 2012
    Posts:
    124
    And here's some of the relevant source code.

    Code (CSharp):
    1.  
    2. private void Update()
    3. {
    4. .....
    5.  
    6. if (Time.time > nextActionTime)
    7.             {
    8.                 // Get distance to player
    9.                 if (passengerData.passenger == null || RegisteredPlayerFSM.Instance.playerGO == null) return;
    10.                 float dist = Vector3.Distance(passengerData.passenger.transform.position, RegisteredPlayerFSM.Instance.playerGO.transform.position);
    11.                 // If within range, enable LookAt method and JumpingJacks animation
    12.                 if (dist < 50f)
    13.                 {
    14.                     if (characterMeshRenderer.isVisible)
    15.                     {
    16.                         watchPlayerEnabled = true;
    17.                         if (passengerData.pedestrianPoolSettings.canAnimate && !jumpingJacksPlaying)
    18.                         {
    19.                             passengerData.randomPhrasesAndReactions.animator.Play("Pas-End-jumping_jacks", -1, 0); // Play jumping jacks to alert the player.
    20.                             Debug.Log("Should be playing animation now - wtf?");
    21.                             jumpingJacksPlaying = true; // This conditional does indeed get set to "true" in my tests
    22.                         }
    23.                     }
    24.                     else
    25.                     {
    26.                         jumpingJacksPlaying = false;
    27.                         watchPlayerEnabled = false;
    28.                     }
    29.                 }
    30.                 // Otherwise, stop the LookAt method and replace JumpingJacks animation with a different animation
    31.                 else
    32.                 {
    33.                     watchPlayerEnabled = false;
    34.                     jumpingJacksPlaying = false;
    35.                     if (passengerData.pedestrianPoolSettings.canAnimate)
    36.                     {
    37.                         passengerData.randomPhrasesAndReactions.animator.Play(passengerData.pedestrianFSM.initState.standingAnims[(int)Random.Range(0, passengerData.pedestrianFSM.initState.standingAnims.Count)].name, -1, 0); // Go to a random animation from Init State
    38.                         jumpingJacksPlaying = false;
    39.                     }
    40.  
    41.                 }
    42.  
    43.                 nextActionTime = Time.time + period;
    44.             }
    45. .....
    46. }
     
    Last edited: Mar 21, 2022
  3. kumade

    kumade

    Joined:
    Nov 3, 2016
    Posts:
    52
    Having the same issue!
    I have different types of enemies. They have the same prefab layouts with the only difference that some of them I animated in Unity editor (used MeshRenderer and animated only basic transforms) and some have animations imported from fbx (they have SkinnedMeshRenderer and bone-based anims). All animators for both types of enemies are set to "Cull Completely".
    So the enemies that have simple MeshRenderers (not Skinned) play animation when visible and do not play when out of the camera frame.
    The ones with SkinnedMeshRenderer always have their animations stalled no matter the camera position. If I change culling mode to "Always animate" they start moving but I don't want that as it's just wasting of resources. Bounds in the SkinnedMeshRenderer component are set correctly, I can see them when I press "Edit Bounds". And nothing covers the objects, they're fully visible on a test scene.

    My Unity version is 2020.1.17f.

    Any chances someone knows how to fix this?