private static List <SpineData.AnimationDrawOrderData> ParseDrawOrders(SpineArmatureEditor armatureEditor, Bones2D.JSONArray drawOrdersArray)
        {
            List <SpineData.AnimationDrawOrderData> animDrawOrders = new List <SpineData.AnimationDrawOrderData>();

            if (drawOrdersArray != null && drawOrdersArray.Count > 0)
            {
                for (int i = 0; i < drawOrdersArray.Count; ++i)
                {
                    Bones2D.JSONClass drawOrderObj             = drawOrdersArray[i].AsObject;
                    SpineData.AnimationDrawOrderData orderData = new SpineData.AnimationDrawOrderData();

                    orderData.time = drawOrderObj["time"].AsFloat;
                    if (drawOrderObj.ContainKey("offsets"))
                    {
                        Bones2D.JSONArray offsetsObj = drawOrderObj["offsets"].AsArray;
                        orderData.offsets = new SpineData.DrawOrderOffset[offsetsObj.Count];
                        for (int j = 0; j < offsetsObj.Count; ++j)
                        {
                            Bones2D.JSONClass offsetObj = offsetsObj[j].AsObject;

                            SpineData.DrawOrderOffset offset = new SpineData.DrawOrderOffset();
                            offset.slotName = offsetObj["slot"].ToString();
                            if (offsetObj.ContainKey("offset"))
                            {
                                offset.offset = offsetObj["offset"].AsInt;
                                //the last offset is 0
                                if (offset.offset == 0)
                                {
                                    int lastSlotIdx = armatureEditor.slotsDataKV[offset.slotName].index;
                                    offset.slotName = armatureEditor.armatureData.slots[lastSlotIdx + 1].name;
                                    offset.offset   = -offsetsObj.Count;
                                }
                            }
                            orderData.offsets[j] = offset;
                        }
                    }
                    animDrawOrders.Add(orderData);
                }
            }
            return(animDrawOrders);
        }
        /// <summary>
        /// set draw order
        /// </summary>
        static void CreateAnimDrawOrder(SpineArmatureEditor armatureEditor, AnimationClip clip, SpineData.AnimationDrawOrderData[] orderDatas)
        {
            int            len           = orderDatas.Length;
            AnimationCurve armatureCurve = new AnimationCurve();
            Dictionary <string, AnimationCurve> slotZOrderKV = new Dictionary <string, AnimationCurve>();

            for (int i = 0; i < len; ++i)
            {
                SpineData.AnimationDrawOrderData frameData = orderDatas[i];
                if (frameData.offsets != null && frameData.offsets.Length > 0)
                {
                    for (int z = 0; z < frameData.offsets.Length; ++z)
                    {
                        SpineData.DrawOrderOffset offset = frameData.offsets[z];
                        Slot slot = armatureEditor.slotsKV[offset.slotName].GetComponent <Slot>();

                        string path = "";
                        if (slotPathKV.ContainsKey(offset.slotName))
                        {
                            path = slotPathKV[offset.slotName];
                        }
                        else
                        {
                            path = GetNodeRelativePath(armatureEditor, slot.transform);
                            slotPathKV[offset.slotName] = path;
                        }

                        AnimationCurve curve = null;
                        if (slotZOrderKV.ContainsKey(offset.slotName))
                        {
                            curve = slotZOrderKV[offset.slotName];
                        }
                        else
                        {
                            curve = new AnimationCurve();
                            slotZOrderKV[offset.slotName] = curve;
                        }
                        if (curve.length == 0 && frameData.time > 0)
                        {
                            //first key
                            curve.AddKey(new Keyframe(0, 0, float.PositiveInfinity, float.PositiveInfinity));
                        }
                        if (orderDatas.Length == i + 1)
                        {
                            //last
                            curve.AddKey(new Keyframe(orderDatas[orderDatas.Length - 1].time, offset.offset, float.PositiveInfinity, float.PositiveInfinity));
                        }
                        curve.AddKey(new Keyframe(frameData.time, offset.offset, float.PositiveInfinity, float.PositiveInfinity));

                        //set Armature zorder invalid
                        ++tempZNumber;
                        armatureCurve.AddKey(new Keyframe(frameData.time, tempZNumber, float.PositiveInfinity, float.PositiveInfinity));
                    }

                    for (int z = 0; z < armatureEditor.slots.Count; ++z)
                    {
                        Slot slot = armatureEditor.slots[z];
                        bool flag = true;
                        for (int t = 0; t < frameData.offsets.Length; ++t)
                        {
                            string slotname = frameData.offsets[t].slotName;
                            if (slot.name.Equals(slotname))
                            {
                                flag = false;
                                break;
                            }
                        }
                        if (flag)
                        {
                            string path = "";
                            if (slotPathKV.ContainsKey(slot.name))
                            {
                                path = slotPathKV[slot.name];
                            }
                            else
                            {
                                path = GetNodeRelativePath(armatureEditor, slot.transform);
                                slotPathKV[slot.name] = path;
                            }

                            AnimationCurve curve = null;
                            if (slotZOrderKV.ContainsKey(slot.name))
                            {
                                curve = slotZOrderKV[slot.name];
                                curve.AddKey(new Keyframe(frameData.time, 0, float.PositiveInfinity, float.PositiveInfinity));
                            }
                        }
                    }
                }
                else
                {
                    for (int z = 0; z < armatureEditor.slots.Count; ++z)
                    {
                        Slot   slot = armatureEditor.slots[z];
                        string path = "";
                        if (slotPathKV.ContainsKey(slot.name))
                        {
                            path = slotPathKV[slot.name];
                        }
                        else
                        {
                            path = GetNodeRelativePath(armatureEditor, slot.transform);
                            slotPathKV[slot.name] = path;
                        }

                        AnimationCurve curve = null;
                        if (slotZOrderKV.ContainsKey(slot.name))
                        {
                            curve = slotZOrderKV[slot.name];
                        }
                        else
                        {
                            curve = new AnimationCurve();
                            slotZOrderKV[slot.name] = curve;
                        }
                        curve.AddKey(new Keyframe(frameData.time, 0, float.PositiveInfinity, float.PositiveInfinity));
                    }

                    //set Armature zorder invalid
                    ++tempZNumber;
                    armatureCurve.AddKey(new Keyframe(frameData.time, tempZNumber, float.PositiveInfinity, float.PositiveInfinity));
                }
            }
            foreach (string name in slotZOrderKV.Keys)
            {
                AnimationCurve zOrderCurve = slotZOrderKV[name];
                CurveExtension.OptimizesCurve(zOrderCurve);
                if (zOrderCurve != null && zOrderCurve.keys != null && zOrderCurve.keys.Length > 0 && CheckCurveValid(zOrderCurve, 0))
                {
                    clip.SetCurve(slotPathKV[name], typeof(Slot), "m_z", zOrderCurve);
                }
            }

            if (armatureCurve.keys.Length > 0)
            {
                clip.SetCurve("", typeof(Armature), "m_ZOrderValid", armatureCurve);

                //add pose
                ++tempZNumber;
                AnimationCurve posezordercurve = new AnimationCurve();
                posezordercurve.AddKey(new Keyframe(0f, tempZNumber));
                AnimationUtility.SetEditorCurve(poseClip, EditorCurveBinding.FloatCurve("", typeof(Armature), "m_ZOrderValid"), posezordercurve);
            }
        }