Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Character Cloth with Final IK (with GIFs)
#5
Hi,

Just chiming in to clarify some of the things said in this thread. Thanks to Partel for contributing a solution!


Quote:The "Obi Animator Controller" has been added into my GameObject later after I played the scene.
Turn this component off makes my obiCloth animation works flawlessly with Final IK. Lengua

Disabling the ObiAnimationController is not a good idea. It makes sure to update the Animator right before cloth simulation takes place, so disabling it can introduce a delay between animation and simulation (due to animation happening after simulation each frame, instead of before). This is the order in which things should happen every frame:

- Unity's Animator component updates bone positions.
- FinalIK applies IK constraints to bones.
- Obi uses bone transforms to update cloth simulation.

Partel's solution will work, as it achieves this update order.

Edit: a minor hint though: creating an event delegate in ObiAnimatorController.cs and calling it before animator.Update will allow you to hook custom code after the animator is updated. In 4.1, modifying the animator like this:

Code:
using UnityEngine;
using System;

namespace Obi
{
    [RequireComponent(typeof(Animator))]
    [DisallowMultipleComponent]
    public class ObiAnimatorController : MonoBehaviour
    {
        private Animator animator;
        private float lastUpdate;
        private float updateDelta;

        public event System.EventHandler OnAnimatorUpdated;

        public float UpdateDelta{
            get{return updateDelta;}
        }

        public void Awake(){
            animator = GetComponent<Animator>();
            lastUpdate = Time.time;
        }

        public void OnDisable(){
            ResumeAutonomousUpdate();
        }

        public void UpdateAnimation(bool fixedUpdate)
        {
            // UpdateAnimation might becalled during FixedUpdate(), but we still need to account for the full frame's worth of animation.
            // Since Time.deltaTime returns the fixed step during FixedUpdate(), we need to use our own delta.
            updateDelta = Time.time - lastUpdate;
            lastUpdate = Time.time;

            if (animator.updateMode == AnimatorUpdateMode.AnimatePhysics)
                updateDelta = Time.fixedDeltaTime;

            // Note: when using AnimatorUpdateMode.Normal, the update method of your character controller
            // should be Update() instead of FixedUpdate() (ObiCharacterController.cs, in this case).

            if (animator != null && isActiveAndEnabled && (animator.updateMode != AnimatorUpdateMode.AnimatePhysics || fixedUpdate)){
                animator.enabled = false;
                animator.Update(updateDelta);

                if (OnAnimatorUpdated != null)
                    OnAnimatorUpdated(this,EventArgs.Empty);
            }
        }

        public void ResumeAutonomousUpdate(){
            if (animator != null){
                animator.enabled = true;
            }
        }
    }
}

allows you to do:

Code:
animationController.OnAnimatorUpdated += <custom function here>;

So, you can do this instead of having to create an assembly definition file for FinalIK:

Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using RootMotion.FinalIK;
using Obi;

public class FinalIKUpdater : MonoBehaviour {

    public ObiAnimatorController controller;
    public IK[] IKComponents;

    void Start () {

        foreach (IK ik in IKComponents)
            ik.enabled = false;
       
        controller.OnAnimatorUpdated += UpdateFinalIKSolvers;
    }

    void UpdateFinalIKSolvers (object sender, System.EventArgs e)
    {
        foreach (IK ik in IKComponents)
         ik.GetIKSolver().Update();
    }

}
Reply


Messages In This Thread
RE: Character Cloth with Final IK (with GIFs) - by josemendez - 15-04-2019, 07:56 PM