Announcement

Collapse
No announcement yet.

Initialization Order of Animation is garbage

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [PROGRAMMING] Initialization Order of Animation is garbage

    Skeletal Mesh Components are a hell to work with if you want to bind Delegates and such before the animation initializes.
    Because no matter what you do, the Animation is initialized AND TICKS before PostInitializeComponents is called (The Function of choice when you want to interconnect Components, similar to Unity's "Awake()")
    And if that's not enough, it also differs between ACharacter and APawn (SkeletalMeshComponent is added via Blueprint Editor)
    Here is a Screenshot of ACharacter derived:
    Click image for larger version  Name:	Character.png Views:	1 Size:	419.0 KB ID:	1604546
    And here is a Screenshot of APawn
    Click image for larger version  Name:	Pawn.png Views:	1 Size:	438.1 KB ID:	1604547


    In the latter case it's even more confusing, since the Animation is even UPDATED before the SkeletalMesh is even Activated
    Valve Epic, pls fix.

    #2
    The UpdateAnimation call, is that the animation blueprint's "tick" function, or a code override?

    Edit: Also, where does PreInitializeComponents fall into the stack? Anything stopping you from using that? Binding to delegates should be safe in there too.
    Last edited by DamirH; 04-07-2019, 07:49 PM.

    Comment


      #3
      Originally posted by DamirH View Post
      The UpdateAnimation call, is that the animation blueprint's "tick" function, or a code override?

      Its the AnimBlueprints "Update Animation" event.

      Originally posted by DamirH View Post
      Edit: Also, where does PreInitializeComponents fall into the stack? Anything stopping you from using that? Binding to delegates should be safe in there too.
      Click image for larger version

Name:	Unbenannt.jpg
Views:	309
Size:	22.0 KB
ID:	1604693

      Comment


        #4
        Animations are ticked once when InitAnim() in the Skeletal Mesh is called - I suspect this is because otherwise there will be a frame or two where the mesh will appear in it's default pose, since anims are usually updated on another thread.

        The Skeletal Mesh Component calls InitAnim when the component is registered via OnRegister() - where it manually ticks the animation with zero delta time. OnRegister() is called before any kind of component initialization.

        https://docs.unrealengine.com/en-us/...ActorLifecycle

        I suspect it differs in ACharacter because characters regularly change the "bOnlyAllowAutonomousTickPose" value so that animation properly links up with networked movement - otherwise the animation would be ticking in between updates which you don't want.
        Last edited by TheJamsh; 04-08-2019, 04:07 AM.

        Comment


          #5
          But thats insane. Update Animation is accessing components (cached or non-cached). These components are not there before PostInitializeComponents, causing lots of Null References.
          You would need to make a Branch "IsInitialized" in UpdateAnimation to forbid the Access on Null Components.
          I already had this problem in the past. To me it looks like there is absolutely NO solution for this.

          Comment


            #6
            Okay, so I have a workaround for this.

            You simply set the Animation Instance to Null in the constructor and set the correct AnimInstance (AnimationBlueprint) on the Instance via Blueprint/World Outliner where you want it (in my case, in PostInitializeComponent)
            It's hacky, but it works and I would like to see a better initialization order in the future.
            Click image for larger version

Name:	Unbenannt.png
Views:	320
Size:	546.4 KB
ID:	1604945

            Comment


              #7
              I think the "by the books" solution to this is to have your custom UAnimInstance subclass and inject whatever you need into that class' OnRegister() function.

              Comment


                #8
                Originally posted by DamirH View Post
                I think the "by the books" solution to this is to have your custom UAnimInstance subclass and inject whatever you need into that class' OnRegister() function.
                that would mean fiddle around in USkeletalMeshComponent's OnRegister / InitAnim function. That doesnt sound well either.
                It also gets Initialized multiple Times.
                OnRegister and InitializeComponent.

                Comment


                  #9
                  Interesting. What a mess.

                  Comment

                  Working...
                  X