Ragdoll Workshop and "Final IK" & "Bone Controller"

322 views
Skip to first unread message

pedro...@gmail.com

unread,
Aug 14, 2015, 6:24:52 PM8/14/15
to Developer Support
Hi... and very good software!!!

I would like to know if your asset (Ragdoll Workshop) is compatible with "Final IK" and/or "Bone Controller".


Bone Controller
https://www.assetstore.unity3d.com/en/#!/content/31483

Final IK
https://www.assetstore.unity3d.com/en/#!/content/14290


Thanks in advance.

Developer Support

unread,
Aug 14, 2015, 11:42:45 PM8/14/15
to Developer Support
Hi Pedro,

3.0.0b3 added support for Final IK (see here), but you have to fix a couple bugs in Final IK right now until the developer publishes an update. You can see more details in the Bugs section here.

I'm not familiar with Bone Controller, but it depends on how the package author has implemented all of the procedural motion. Basically, they need a way to compute the results of the motion on-demand, as opposed to simply applying it in LateUpdate() (which is the common approach). You'd then have to make a script that works like my RagdollAnimatorFinalIKSync component and just subscribe to the right events (this page may help).

marck...@gmail.com

unread,
Aug 15, 2015, 10:26:30 PM8/15/15
to Developer Support
Thanks both of you.
I contacted the developer of BoneController asking if their asset works with Ragdoll Workshop.

I'll let you know any news.

Thanks again.

marck...@gmail.com

unread,
Aug 25, 2015, 4:29:37 PM8/25/15
to Developer Support
Developer support:
I was reading the forum of BoneController and "Tryz" says:

**********************
Short answer: If you manage enabling/disabling the BC motors, they should work together.

All of BC's work is done in LateUpdate(). I actually batch all the bone change requests (made through motors) and then apply them at the end of the update.

You can disable all the BC motors and then any other package (like Ragdoll Workshop) can take over. Assuming Ragdoll Workshop "turns on" and "turns off", you can just make sure only one asset is active at a time. When you're ready for BC to start working again, you'd just re-enable the motors that should run.

I hope that helps.
******************

Please read the original post:
http://forum.unity3d.com/threads/bone-controller-released.298345/page-4#post-2253160


Developer Support

unread,
Aug 27, 2015, 10:34:12 AM8/27/15
to Developer Support
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.IKm_IKSolvers = new List<RootMotion.FinalIK.IK>();
        /// <summary>
        /// All of the Grounders found in the hierarchy.
        /// </summary>
        private List<RootMotion.FinalIK.Grounderm_Grounders = new List<RootMotion.FinalIK.Grounder>();
        
        #region Backing Fields
        [SerializeFieldHideInInspector]
        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 = 0i < 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 = 0i < m_Grounders.Count; ++i)
            {
                if (m_Grounders[i] != null)
                {
                    m_Grounders[i].weight = animator.FullHierarchyBlendProgress;
                }
            }
            for (int i = 0i < 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 = 0i < 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));
        }
    }
}

Reply all
Reply to author
Forward
0 new messages