private void UpdateDynamicBone(DynamicBone dynamicBone, bool isSetValue = false, float dampFloat = 0f,
                                   float elastFloat      = 0f, float stiffFloat  = 0f,
                                   float inertFloat      = 0f, float radiusFloat = 0f,
                                   float endOffsetX      = 0f, float endOffsetY  = 0f, float endOffsetZ = 0f, // End offset vec3
                                   float gravityX        = 0f, float gravityY    = 0f, float gravityZ   = 0f, // gravity vec3
                                   float forceX          = 0f, float forceY      = 0f, float forceZ     = 0f, // force vec3
                                   float updateRateFloat = 0f,
                                   DynamicBonesPreset dynamicBonePreset = null)
    {
        var dynamicBoneTarget = dynamicBone;
        var dynamicBoneSo     = new SerializedObject(dynamicBoneTarget);
        var root       = dynamicBoneSo.FindProperty("m_Root");
        var updateRate = dynamicBoneSo.FindProperty("m_UpdateRate");
        var damp       = dynamicBoneSo.FindProperty("m_Damping");
        var elast      = dynamicBoneSo.FindProperty("m_Elasticity");
        var stiff      = dynamicBoneSo.FindProperty("m_Stiffness");
        var inert      = dynamicBoneSo.FindProperty("m_Inert");
        var radius     = dynamicBoneSo.FindProperty("m_Radius");
        var endLength  = dynamicBoneSo.FindProperty("m_EndLength");
        var endOffset  = dynamicBoneSo.FindProperty("m_EndOffset");
        var grav       = dynamicBoneSo.FindProperty("m_Gravity");
        var force      = dynamicBoneSo.FindProperty("m_Force");
        var colliders  = dynamicBoneSo.FindProperty("m_Colliders");
        var exclusions = dynamicBoneSo.FindProperty("m_Exclusions");

        if (isSetValue)
        {
            if (dynamicBonePreset != null)
            {
                dampFloat       = dynamicBonePreset.Damping;
                updateRateFloat = dynamicBonePreset.UpdateRate;
                elastFloat      = dynamicBonePreset.Elasticity;
                stiffFloat      = dynamicBonePreset.Stiffness;
                inertFloat      = dynamicBonePreset.Inert;
                radiusFloat     = dynamicBonePreset.Radius;

                endOffsetX = dynamicBonePreset.EndOffset.x;
                endOffsetY = dynamicBonePreset.EndOffset.y;
                endOffsetZ = dynamicBonePreset.EndOffset.z;

                gravityX = dynamicBonePreset.Gravity.x;
                gravityY = dynamicBonePreset.Gravity.y;
                gravityZ = dynamicBonePreset.Gravity.z;

                forceX = dynamicBonePreset.Force.x;
                forceY = dynamicBonePreset.Force.y;
                forceZ = dynamicBonePreset.Force.z;
            }
            updateRate.floatValue  = updateRateFloat;
            damp.floatValue        = dampFloat;
            elast.floatValue       = elastFloat;
            stiff.floatValue       = stiffFloat;
            inert.floatValue       = inertFloat;
            radius.floatValue      = radiusFloat;
            endOffset.vector3Value = new Vector3(endOffsetX, endOffsetY, endOffsetZ);
            grav.vector3Value      = new Vector3(gravityX, gravityY, gravityZ);
            force.vector3Value     = new Vector3(forceX, forceY, forceZ);
        }

        EditorGUI.indentLevel = 1;
        {
            EditorGUILayout.PropertyField(updateRate, true, new[] { GUILayout.ExpandWidth(false) });
            EditorGUILayout.PropertyField(damp, true);
            EditorGUILayout.PropertyField(elast, true);
            EditorGUILayout.PropertyField(stiff, true);
            EditorGUILayout.PropertyField(inert, true);
            EditorGUILayout.PropertyField(radius, true);
            EditorGUILayout.PropertyField(endLength, true);

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.PropertyField(endOffset, true, new[] { GUILayout.ExpandWidth(false) });
                EditorGUILayout.PropertyField(grav, true, new[] { GUILayout.ExpandWidth(false) });
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.PropertyField(force, true, new[] { GUILayout.ExpandWidth(false) });

            EditorGUILayout.BeginHorizontal();
            {
                EditorGUILayout.PropertyField(colliders, true, new[] { GUILayout.ExpandWidth(false) });
                EditorGUILayout.PropertyField(exclusions, true, new[] { GUILayout.ExpandWidth(false) });
            }
            EditorGUILayout.EndHorizontal();
        }
        EditorGUI.indentLevel = 0;

        dynamicBoneSo.ApplyModifiedProperties();
    }
    private DynamicBonesPreset LoadSingleDynamicBonePreset(string presetName)
    {
        if (_configFile == null)
        {
            InitConfigFile();
        }
        if (presetName == null)
        {
            return(null);
        }
        var section           = _configFile.GetSection(presetName);
        var dynamicBonePreset = new DynamicBonesPreset();
        var tempOffsetVec3    = Vector3.zero;
        var tempGravityVec3   = Vector3.zero;
        var tempForceVec3     = Vector3.zero;

        foreach (var sectionKey in section.Keys)
        {
            switch (sectionKey)
            {
            case "Name":
                dynamicBonePreset.Name = section[sectionKey];
                break;

            case "UpdateRate":
                dynamicBonePreset.UpdateRate = float.Parse(section[sectionKey]);
                break;

            case "Damp":
                dynamicBonePreset.Damping = float.Parse(section[sectionKey]);
                break;

            case "Elasticity":
                dynamicBonePreset.Elasticity = float.Parse(section[sectionKey]);
                break;

            case "Stiff":
                dynamicBonePreset.Stiffness = float.Parse(section[sectionKey]);
                break;

            case "Inert":
                dynamicBonePreset.Inert = float.Parse(section[sectionKey]);
                break;

            case "Radius":
                dynamicBonePreset.Radius = float.Parse(section[sectionKey]);
                break;

            case "EndOffsetX":
                tempOffsetVec3.x = float.Parse(section[sectionKey]);
                break;

            case "EndOffsetY":
                tempOffsetVec3.y = float.Parse(section[sectionKey]);
                break;

            case "EndOffsetZ":
                tempOffsetVec3.z = float.Parse(section[sectionKey]);
                break;

            case "GravityX":
                tempGravityVec3.x = float.Parse(section[sectionKey]);
                break;

            case "GravityY":
                tempGravityVec3.y = float.Parse(section[sectionKey]);
                break;

            case "GravityZ":
                tempGravityVec3.z = float.Parse(section[sectionKey]);
                break;

            case "ForceX":
                tempForceVec3.x = float.Parse(section[sectionKey]);
                break;

            case "ForceY":
                tempForceVec3.y = float.Parse(section[sectionKey]);
                break;

            case "ForceZ":
                tempForceVec3.z = float.Parse(section[sectionKey]);
                break;
            }
        }
        dynamicBonePreset.EndOffset = tempOffsetVec3;
        dynamicBonePreset.Gravity   = tempGravityVec3;
        dynamicBonePreset.Force     = tempForceVec3;
        return(dynamicBonePreset);
    }