15-04-2019, 07:56 PM
(This post was last modified: 15-04-2019, 08:13 PM by josemendez.)
Hi,
Just chiming in to clarify some of the things said in this thread. Thanks to Partel for contributing a solution!
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:
allows you to do:
So, you can do this instead of having to create an assembly definition file for FinalIK:
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();
}
}