So unfortunately that's not exactly the way the RagdollAnimator component works. He needs to make sure there are API points for manually controlling the timing of when BC motors are evaluated so the final pose can be sampled during the FixedUpdate() loop. Basically, you need to be able to disable all the BC motor components so they do not automatically update, and you need to be able to call some method from another script to get them to evaluate (e.g., BCMotor.LateUpdate() needs to be public if that's where everything happens). Then, like the
RagdollAnimatorFinalIKSync component, you would need something that disabled the BC motors when the application starts, and adds their LateUpdate methods to the events on the RagdollAnimator. If it's helpful, I've pasted the relevant code from the RagdollAnimatorFinalIKSync component below. You could point the BC developer to this so he or she could understand what I mean.
using UnityEngine;
using System.Collections.Generic;
namespace Candlelight.Physics
{
[RequireComponent(typeof(RagdollAnimator))]
public sealed class RagdollAnimatorFinalIKSync : MonoBehaviour
{
/// <summary>
/// All of the IK solvers found in the hierarchy.
/// </summary>
private List<RootMotion.FinalIK.IK> m_IKSolvers = new List<RootMotion.FinalIK.IK>();
/// <summary>
/// All of the Grounders found in the hierarchy.
/// </summary>
private List<RootMotion.FinalIK.Grounder> m_Grounders = new List<RootMotion.FinalIK.Grounder>();
#region Backing Fields
[SerializeField, HideInInspector]
private RagdollAnimator m_Animator = null;
#endregion
/// <summary>
/// Gets the <see cref="Candlelight.RagdollAnimator"/>.
/// </summary>
/// <value>The <see cref="Candlelight.RagdollAnimator"/>.</value>
public RagdollAnimator Animator
{
get { return m_Animator = m_Animator ?? GetComponent<RagdollAnimator>(); }
}
/// <summary>
/// Resets the transforms prior to applying animation data.
/// </summary>
/// <param name="animator">Animator.</param>
private void ResetTransforms(RagdollAnimator animator)
{
for (int i = 0; i < m_IKSolvers.Count; ++i)
{
if (m_IKSolvers[i] == null)
{
return;
}
if (m_IKSolvers[i].fixTransforms)
{
m_IKSolvers[i].GetIKSolver().FixTransforms();
}
}
}
/// <summary>
/// Solves all IK components after applying animation data.
/// </summary>
/// <param name="animator">Animator.</param>
private void SolveIK(RagdollAnimator animator)
{
for (int i = 0; i < m_Grounders.Count; ++i)
{
if (m_Grounders[i] != null)
{
m_Grounders[i].weight = animator.FullHierarchyBlendProgress;
}
}
for (int i = 0; i < m_IKSolvers.Count; ++i)
{
if (m_IKSolvers[i] != null)
{
m_IKSolvers[i].GetIKSolver().Update();
}
}
}
/// <summary>
/// Register events and initialize Final IK solvers.
/// </summary>
private void Start()
{
this.Animator.OnPreprocessAnimatedHierarchy.AddListener(ResetTransforms);
this.Animator.OnPostprocessInputPose.AddListener(SolveIK);
m_IKSolvers.Clear();
m_IKSolvers.AddRange(GetComponentsInChildren<RootMotion.FinalIK.IK>(true));
for (int i = 0; i < m_IKSolvers.Count; ++i)
{
m_IKSolvers[i].Disable(); /// NOTE: FinalIK requires you use this instead of MonoBehaviour.enabled = false
}
m_Grounders.Clear();
m_Grounders.AddRange(GetComponentsInChildren<RootMotion.FinalIK.Grounder>(true));
}
}
}