/// <summary>
        /// AnimClip이 Control Param을 제어하기 위해서는 이 함수를 호출하여 업데이트를 할 수 있게 해야한다.
        /// [Opt에서는 AnimPlayData를 링크할때 만들어주자]
        /// </summary>
        public void MakeAndLinkControlParamResults()
        {
            if (_controlParamResult == null)
            {
                _controlParamResult = new List <apAnimControlParamResult>();
            }
            _controlParamResult.Clear();

            apAnimTimeline      timeline = null;
            apAnimTimelineLayer layer    = null;

            for (int iTL = 0; iTL < _timelines.Count; iTL++)
            {
                timeline = _timelines[iTL];
                if (timeline._linkType != LINK_TYPE.ControlParam)
                {
                    continue;
                }

                for (int iL = 0; iL < timeline._layers.Count; iL++)
                {
                    layer = timeline._layers[iL];

                    if (layer._linkedControlParam == null)
                    {
                        continue;
                    }

                    apAnimControlParamResult cpResult = GetControlParamResult(layer._linkedControlParam);
                    if (cpResult == null)
                    {
                        cpResult = new apAnimControlParamResult(layer._linkedControlParam);
                        cpResult.Init();
                        _controlParamResult.Add(cpResult);
                    }

                    //레이어와도 연동해주자
                    //ControlParam <- CPResult <- Layer
                    //     ^------------------------]

                    layer._linkedControlParamResult = cpResult;
                }
            }
        }
        /// <summary>
        /// [Editor] 업데이트 중 Control Param 제어 Timeline에 대해 업데이트 후 적용을 한다.
        /// [Runtime] isAdaptToWeight = false로 두고 나머지 처리를 한다.
        /// </summary>
        /// <param name="isAdaptToWeight1">[Editor]에서 Weight=1로 두고 적용을 한다</param>
        public void UpdateControlParam(bool isAdaptToWeight1, int optLayer = 0, float optWeight = 1.0f, apAnimPlayUnit.BLEND_METHOD optBlendMethod = apAnimPlayUnit.BLEND_METHOD.Interpolation)
        {
            if (_controlParamResult.Count == 0)
            {
                return;
            }

            for (int i = 0; i < _controlParamResult.Count; i++)
            {
                _controlParamResult[i].Init();
            }

            apAnimTimeline      timeline = null;
            apAnimTimelineLayer layer    = null;

            int   curFrame  = CurFrame;
            float curFrameF = CurFrameFloat;

            //apAnimKeyframe firstKeyframe = null;
            //apAnimKeyframe lastKeyframe = null;

            apAnimKeyframe curKeyframe  = null;
            apAnimKeyframe prevKeyframe = null;
            apAnimKeyframe nextKeyframe = null;

            int lengthFrames = _endFrame - _startFrame;
            int tmpCurFrame  = 0;

            apAnimControlParamResult cpResult = null;

            for (int iTL = 0; iTL < _timelines.Count; iTL++)
            {
                timeline = _timelines[iTL];
                if (timeline._linkType != LINK_TYPE.ControlParam)
                {
                    continue;
                }

                for (int iL = 0; iL < timeline._layers.Count; iL++)
                {
                    layer = timeline._layers[iL];
                    if (layer._linkedControlParam == null || layer._linkedControlParamResult == null)
                    {
                        continue;
                    }

                    cpResult = layer._linkedControlParamResult;

                    //firstKeyframe = layer._firstKeyFrame;
                    //lastKeyframe = layer._lastKeyFrame;

                    for (int iK = 0; iK < layer._keyframes.Count; iK++)
                    {
                        curKeyframe  = layer._keyframes[iK];
                        prevKeyframe = curKeyframe._prevLinkedKeyframe;
                        nextKeyframe = curKeyframe._nextLinkedKeyframe;

                        if (curFrame == curKeyframe._frameIndex ||
                            ((curKeyframe._isLoopAsStart || curKeyframe._isLoopAsEnd) && curKeyframe._loopFrameIndex == curFrame)
                            )
                        {
                            cpResult.SetKeyframeResult(curKeyframe, 1.0f);
                        }
                        else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Prev))
                        {
                            //Prev - Cur 범위 안에 들었다.
                            if (prevKeyframe != null)
                            {
                                //Prev 키가 있다면
                                tmpCurFrame = curFrame;
                                if (tmpCurFrame > curKeyframe._frameIndex)
                                {
                                    //한바퀴 돌았다면
                                    tmpCurFrame -= lengthFrames;
                                }

                                //TODO : 여길 나중에 "정식 Curve로 변경"할 것
                                //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, prevKeyframe._curveKey, tmpCurFrame, true);

                                //>> 변경
                                float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, true);

                                cpResult.SetKeyframeResult(curKeyframe, itp);
                            }
                            else
                            {
                                //Prev 키가 없다면 이게 100%다
                                cpResult.SetKeyframeResult(curKeyframe, 1.0f);
                            }
                        }
                        else if (curKeyframe.IsFrameIn(curFrame, apAnimKeyframe.LINKED_KEY.Next))
                        {
                            //Cur - Next 범위 안에 들었다.
                            if (nextKeyframe != null)
                            {
                                //Next 키가 있다면
                                tmpCurFrame = curFrame;
                                if (tmpCurFrame < curKeyframe._frameIndex)
                                {
                                    //한바퀴 돌았다면
                                    tmpCurFrame += lengthFrames;
                                }

                                //TODO : 여길 나중에 "정식 Curve로 변경"할 것
                                //float itp = apAnimCurve.GetCurvedRelativeInterpolation(curKeyframe._curveKey, nextKeyframe._curveKey, tmpCurFrame, false);

                                //>> 변경
                                float itp = curKeyframe._curveKey.GetItp_Int(tmpCurFrame, false);

                                cpResult.SetKeyframeResult(curKeyframe, itp);
                            }
                            else
                            {
                                //Prev 키가 없다면 이게 100%다
                                cpResult.SetKeyframeResult(curKeyframe, 1.0f);
                            }
                        }
                    }
                }
            }


            //Control Param에 적용을 해야한다.
            if (isAdaptToWeight1)
            {
                //Editor인 경우 Weight 1로 강제한다.
                for (int i = 0; i < _controlParamResult.Count; i++)
                {
                    _controlParamResult[i].AdaptToControlParam();
                }
            }
            else
            {
                //Runtime인 경우 지정된 Weight, Layer로 처리한다.
                for (int i = 0; i < _controlParamResult.Count; i++)
                {
                    //Debug.Log("AnimClip [" + _name + " > Control Param : " + _controlParamResult[i]._targetControlParam._keyName + " ]");
                    _controlParamResult[i].AdaptToControlParam_Opt(optWeight, optBlendMethod);
                }
            }
        }