Esempio n. 1
0
        // Functions
        //-----------------------------------------------
        // Event -> File
        //--------------------------------------------------------------
        public void SetAnimationEvent(apAnimEvent animEvent)
        {
            _frameIndex     = animEvent._frameIndex;
            _frameIndex_End = animEvent._frameIndex_End;

            _eventName = animEvent._eventName;

            _callType = animEvent._callType;


            _subParams.Clear();
            for (int i = 0; i < animEvent._subParams.Count; i++)
            {
                SubParameter             newSubParam = new SubParameter();
                apAnimEvent.SubParameter srcParam    = animEvent._subParams[i];

                newSubParam._paramType = srcParam._paramType;

                newSubParam._boolValue  = srcParam._boolValue;
                newSubParam._intValue   = srcParam._intValue;
                newSubParam._floatValue = srcParam._floatValue;
                newSubParam._vec2Value  = srcParam._vec2Value;
                newSubParam._strValue   = srcParam._strValue;

                newSubParam._intValue_End   = srcParam._intValue_End;
                newSubParam._floatValue_End = srcParam._floatValue_End;
                newSubParam._vec2Value_End  = srcParam._vec2Value_End;

                _subParams.Add(newSubParam);
            }
        }
Esempio n. 2
0
        //------------------------------------------------------------------------------
        // Copy For Bake
        //------------------------------------------------------------------------------
        public void CopyFromAnimEvent(apAnimEvent srcEvent)
        {
            _frameIndex     = srcEvent._frameIndex;
            _frameIndex_End = srcEvent._frameIndex_End;

            _eventName = srcEvent._eventName;
            _callType  = srcEvent._callType;

            _subParams.Clear();
            for (int iParam = 0; iParam < srcEvent._subParams.Count; iParam++)
            {
                SubParameter srcParam = srcEvent._subParams[iParam];

                //파라미터 복사
                SubParameter newParam = new SubParameter();

                newParam._paramType = srcParam._paramType;

                newParam._boolValue  = srcParam._boolValue;
                newParam._intValue   = srcParam._intValue;
                newParam._floatValue = srcParam._floatValue;
                newParam._vec2Value  = srcParam._vec2Value;
                newParam._strValue   = srcParam._strValue;

                newParam._intValue_End   = srcParam._intValue_End;
                newParam._floatValue_End = srcParam._floatValue_End;
                newParam._vec2Value_End  = srcParam._vec2Value_End;

                _subParams.Add(newParam);
            }
        }
Esempio n. 3
0
        // Init
        //--------------------------------------------------------------
        public void Init(apEditor editor, apPortrait portrait, apAnimClip animClip)
        {
            _editor   = editor;
            _portrait = portrait;
            _animClip = animClip;

            _curSelectedEvent = null;
            _defaultFrame     = animClip.CurFrame;
        }
        public void ResetEventsBasedFrame(int frame, bool isForward)
        {
            //프레임 이동시에 AnimEvent를 다시 리셋한다.
            if (_animEvents == null || _animEvents.Count == 0)
            {
                return;
            }
            apAnimEvent animEvent = null;
            int         minFrame  = -1;
            int         maxFrame  = -1;

            for (int i = 0; i < _animEvents.Count; i++)
            {
                animEvent = _animEvents[i];
                //일단 초기화
                animEvent.ResetCallFlag();

                if (animEvent._callType == apAnimEvent.CALL_TYPE.Once)
                {
                    minFrame = animEvent._frameIndex;
                    maxFrame = animEvent._frameIndex;
                }
                else
                {
                    minFrame = animEvent._frameIndex;
                    maxFrame = animEvent._frameIndex_End;
                }

                if (isForward)
                {
                    //현재 프레임보다 작다면 모두 Lock
                    if (minFrame < frame && maxFrame < frame)
                    {
                        animEvent.Lock();
                        //UnityEngine.Debug.LogError(" >> Lock [" + animEvent._eventName + "] " + animEvent._frameIndex);
                    }
                }
                else
                {
                    //현재 프레임보다 모두 크다면 모두 Lock
                    if (minFrame > frame && maxFrame > frame)
                    {
                        animEvent.Lock();
                        //UnityEngine.Debug.LogError(" >> Lock [" + animEvent._eventName + "] " + animEvent._frameIndex);
                    }
                }
            }
        }
        //---------------------------------------------------------------------------------------
        // Copy For Bake
        //---------------------------------------------------------------------------------------
        public void CopyFromAnimClip(apAnimClip srcAnimClip)
        {
            _uniqueID = srcAnimClip._uniqueID;
            _name     = srcAnimClip._name;

            _targetMeshGroupID = srcAnimClip._targetMeshGroupID;
            _targetMeshGroup   = null;
            _targetOptTranform = null;

            _FPS         = srcAnimClip._FPS;
            _secPerFrame = srcAnimClip._secPerFrame;            //수정 3.31 : 이게 버그의 원인
            _startFrame  = srcAnimClip._startFrame;
            _endFrame    = srcAnimClip._endFrame;
            _isLoop      = srcAnimClip._isLoop;

            //Timeline 복사
            _timelines.Clear();
            for (int iTimeline = 0; iTimeline < srcAnimClip._timelines.Count; iTimeline++)
            {
                apAnimTimeline srcTimeline = srcAnimClip._timelines[iTimeline];

                //Timeline을 복사하자.
                //내부에서 차례로 Layer, Keyframe도 복사된다.
                apAnimTimeline newTimeline = new apAnimTimeline();
                newTimeline.CopyFromTimeline(srcTimeline, this);

                _timelines.Add(newTimeline);
            }

            //AnimEvent 복사
            _animEvents.Clear();
            for (int iEvent = 0; iEvent < srcAnimClip._animEvents.Count; iEvent++)
            {
                apAnimEvent srcEvent = srcAnimClip._animEvents[iEvent];

                //Event 복사하자
                apAnimEvent newEvent = new apAnimEvent();
                newEvent.CopyFromAnimEvent(srcEvent);

                _animEvents.Add(newEvent);
            }
        }
Esempio n. 6
0
        // GUI
        //--------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

            if (_editor == null || _editor._portrait == null || _editor._portrait != _portrait)
            {
                return;
            }

            bool isGUIEvent = (Event.current.type == EventType.Repaint || Event.current.type == EventType.Layout);


            EditorGUILayout.BeginVertical();

            Texture2D iconImageAnimation = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_Animation);
            Texture2D iconImageCategory  = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_FoldDown);
            Texture2D iconImageAddParam  = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_Add);
            Texture2D iconImageLayerUp   = _editor.ImageSet.Get(apImageSet.PRESET.Modifier_LayerUp);
            Texture2D iconImageLayerDown = _editor.ImageSet.Get(apImageSet.PRESET.Modifier_LayerDown);
            Texture2D iconImageRemove    = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_RemoveTransform);

            GUIStyle guiStyleBox = new GUIStyle(GUI.skin.box);

            guiStyleBox.alignment        = TextAnchor.MiddleCenter;
            guiStyleBox.normal.textColor = apEditorUtil.BoxTextColor;

            //"  [ " + _animClip._name + " ] Animation Events"

            //변경
            if (_guiContent_AnimClipName == null)
            {
                _guiContent_AnimClipName = apGUIContentWrapper.Make(string.Format("  [ {0} ] {1}", _animClip._name, _editor.GetText(TEXT.DLG_AnimationEvents)), false, iconImageAnimation);
            }
            if (_guiContent_Range == null)
            {
                _guiContent_Range = apGUIContentWrapper.Make(string.Format("{0} : {1} ~ {2}", _editor.GetText(TEXT.DLG_Range), _animClip.StartFrame, _animClip.EndFrame), false);
            }
            if (_guiContent_IsLoop == null)
            {
                _guiContent_IsLoop = apGUIContentWrapper.Make(string.Format("{0} : {1}", _editor.GetText(TEXT.DLG_IsLoopAnimation), _animClip.IsLoop), false);
            }


            GUILayout.Box(_guiContent_AnimClipName.Content, guiStyleBox, GUILayout.Width(width - 10), GUILayout.Height(35));

            GUILayout.Space(5);
            //"Range : " + _animClip.StartFrame + " ~ " + _animClip.EndFrame
            EditorGUILayout.LabelField(_guiContent_Range.Content);

            //"Is Loop Animation : " + _animClip.IsLoop
            EditorGUILayout.LabelField(_guiContent_IsLoop.Content);

            GUILayout.Space(10);

            GUIStyle guiStyle_None = new GUIStyle(GUIStyle.none);

            guiStyle_None.normal.textColor = GUI.skin.label.normal.textColor;
            guiStyle_None.alignment        = TextAnchor.MiddleLeft;

            GUIStyle guiStyle_Selected = new GUIStyle(GUIStyle.none);

            if (EditorGUIUtility.isProSkin)
            {
                guiStyle_Selected.normal.textColor = Color.cyan;
            }
            else
            {
                guiStyle_Selected.normal.textColor = Color.white;
            }
            guiStyle_Selected.alignment = TextAnchor.MiddleLeft;

            GUIStyle guiStyle_Center = new GUIStyle(GUIStyle.none);

            guiStyle_Center.normal.textColor = GUI.skin.label.normal.textColor;
            guiStyle_Center.alignment        = TextAnchor.MiddleCenter;


            int topHeight    = 120;
            int bottomHeight = 380;


            Color prevColor = GUI.backgroundColor;

            GUI.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
            GUI.Box(new Rect(0, topHeight - 26, width, height - (topHeight + bottomHeight)), "");
            GUI.backgroundColor = prevColor;



            _scrollList = EditorGUILayout.BeginScrollView(_scrollList, GUILayout.Width(width), GUILayout.Height(height - (topHeight + bottomHeight)));
            GUILayout.Space(5);
            //"Animation Events"
            if (_guiContent_AnimEventCategory == null)
            {
                _guiContent_AnimEventCategory = apGUIContentWrapper.Make(_editor.GetText(TEXT.DLG_AnimationEvents), false, iconImageCategory);
            }


            GUILayout.Button(_guiContent_AnimEventCategory.Content, guiStyle_None, GUILayout.Height(20));            //<투명 버튼//

            int nAnimEvents = 0;

            if (_animClip._animEvents != null)
            {
                nAnimEvents = _animClip._animEvents.Count;
            }

            //GUILayout.Space(10);
            apAnimEvent animEvent = null;

            for (int i = 0; i < nAnimEvents; i++)
            {
                GUIStyle curGUIStyle = guiStyle_None;
                animEvent = _animClip._animEvents[i];

                if (animEvent == _curSelectedEvent)
                {
                    Rect lastRect = GUILayoutUtility.GetLastRect();
                    prevColor = GUI.backgroundColor;

                    if (EditorGUIUtility.isProSkin)
                    {
                        GUI.backgroundColor = new Color(0.0f, 1.0f, 1.0f, 1.0f);
                    }
                    else
                    {
                        GUI.backgroundColor = new Color(0.4f, 0.8f, 1.0f, 1.0f);
                    }

                    GUI.Box(new Rect(lastRect.x, lastRect.y + 21, width, 20), "");
                    GUI.backgroundColor = prevColor;

                    curGUIStyle = guiStyle_Selected;
                }


                EditorGUILayout.BeginHorizontal(GUILayout.Width(width - 50));
                GUILayout.Space(15);
                if (GUILayout.Button("[" + i + "] " + animEvent._eventName, curGUIStyle, GUILayout.Width(width - 80), GUILayout.Height(20)))
                {
                    _curSelectedEvent = animEvent;
                }

                if (animEvent._callType == apAnimEvent.CALL_TYPE.Once)
                {
                    if (GUILayout.Button(animEvent._frameIndex.ToString(), curGUIStyle, GUILayout.Width(45), GUILayout.Height(20)))
                    {
                        _curSelectedEvent = animEvent;
                    }
                }
                else
                {
                    if (GUILayout.Button(animEvent._frameIndex + " ~ " + animEvent._frameIndex_End, curGUIStyle, GUILayout.Width(45), GUILayout.Height(20)))
                    {
                        _curSelectedEvent = animEvent;
                    }
                }

                EditorGUILayout.EndHorizontal();
            }

            GUILayout.Space((height - (topHeight + bottomHeight)) + 100);
            EditorGUILayout.EndScrollView();

            EditorGUILayout.EndVertical();

            GUILayout.Space(10);
            EditorGUILayout.BeginHorizontal(GUILayout.Height(30));
            GUILayout.Space(5);

            //"Add Event"
            if (GUILayout.Button(_editor.GetText(TEXT.DLG_AddEvent), GUILayout.Width(width - (10 + 6 + (160))), GUILayout.Height(30)))
            {
                apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_AddEvent, _editor, _animClip._portrait, null, false);

                if (_animClip._animEvents == null)
                {
                    _animClip._animEvents = new List <apAnimEvent>();
                }

                apAnimEvent newEvent = new apAnimEvent();
                //새로운 이름을 찾자
                int    iNewName = 0;
                string newName  = "NewAnimEvent_" + iNewName;

                int cnt = 0;
                while (true)
                {
                    if (cnt > 500)
                    {
                        newName = "NewAnimEvent_Infinity";
                        break;
                    }
                    //중복되는 이름이 있는가
                    newName = "NewAnimEvent_" + iNewName;
                    bool isExist = _animClip._animEvents.Exists(delegate(apAnimEvent a)
                    {
                        return(string.Equals(a._eventName, newName));
                    });
                    if (!isExist)
                    {
                        //중복되지 않는 이름이다.
                        break;
                    }

                    //이름이 중복되는 군염
                    cnt++;
                    iNewName++;
                }

                newEvent._eventName  = newName;
                newEvent._frameIndex = _defaultFrame;

                _animClip._animEvents.Add(newEvent);

                _curSelectedEvent = newEvent;
            }

            //추가 3.29 : 이벤트 복사하기 : 프레임은 무조건 다음 프레임에
            string strCopy = _editor.GetUIWord(UIWORD.Copy);

            //if(GUILayout.Button(_editor.GetUIWord(UIWORD.Copy), GUILayout.Width(80), GUILayout.Height(30)))
            if (apEditorUtil.ToggledButton_2Side(strCopy, strCopy, false, _curSelectedEvent != null, 80, 30))
            {
                if (_curSelectedEvent != null)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_AddEvent, _editor, _animClip._portrait, null, false);

                    if (_animClip._animEvents == null)
                    {
                        _animClip._animEvents = new List <apAnimEvent>();
                    }

                    apAnimEvent newEvent = new apAnimEvent();

                    //선택한 이벤트와 동일한 속성으로 설정.
                    //- _defaultFrame과 다르다면, 거기에 복사
                    //- _defaultFrame과 같다면 +1프레임
                    newEvent._eventName = _curSelectedEvent._eventName;
                    newEvent._callType  = _curSelectedEvent._callType;

                    if (newEvent._callType == apAnimEvent.CALL_TYPE.Once)
                    {
                        if (_curSelectedEvent._frameIndex == _defaultFrame)
                        {
                            newEvent._frameIndex     = _curSelectedEvent._frameIndex + 1;
                            newEvent._frameIndex_End = _curSelectedEvent._frameIndex_End + 1;
                        }
                        else
                        {
                            int frameLength = Mathf.Max(_curSelectedEvent._frameIndex_End - _curSelectedEvent._frameIndex, 0);

                            newEvent._frameIndex     = _defaultFrame;
                            newEvent._frameIndex_End = newEvent._frameIndex + frameLength;
                        }
                    }
                    else
                    {
                        int frameLength = Mathf.Max(_curSelectedEvent._frameIndex_End - _curSelectedEvent._frameIndex, 0);

                        if (_curSelectedEvent._frameIndex <= _defaultFrame && _defaultFrame <= _curSelectedEvent._frameIndex + frameLength)
                        {
                            //DefaultFrame이 기존 이벤트 영역에 포함되어 있다.
                            //기존 영역의 밖에서 생성
                            newEvent._frameIndex     = _curSelectedEvent._frameIndex + frameLength + 1;
                            newEvent._frameIndex_End = newEvent._frameIndex + frameLength;
                        }
                        else
                        {
                            //DefaultFrame이 기존 이벤트 영역 밖에 있다.
                            //DefaultFrame부터 생성
                            newEvent._frameIndex     = _defaultFrame;
                            newEvent._frameIndex_End = newEvent._frameIndex + frameLength;
                        }
                    }

                    if (_curSelectedEvent._subParams == null)
                    {
                        _curSelectedEvent._subParams = new List <apAnimEvent.SubParameter>();
                    }
                    if (_curSelectedEvent._subParams != null)
                    {
                        for (int iParam = 0; iParam < _curSelectedEvent._subParams.Count; iParam++)
                        {
                            apAnimEvent.SubParameter existParam = _curSelectedEvent._subParams[iParam];
                            apAnimEvent.SubParameter newParam   = new apAnimEvent.SubParameter();

                            //속성들 복사
                            newParam._paramType      = existParam._paramType;
                            newParam._boolValue      = existParam._boolValue;
                            newParam._intValue       = existParam._intValue;
                            newParam._floatValue     = existParam._floatValue;
                            newParam._vec2Value      = existParam._vec2Value;
                            newParam._strValue       = existParam._strValue;
                            newParam._intValue_End   = existParam._intValue_End;
                            newParam._floatValue_End = existParam._floatValue_End;
                            newParam._vec2Value_End  = existParam._vec2Value_End;

                            newEvent._subParams.Add(newParam);
                        }
                    }


                    _animClip._animEvents.Add(newEvent);

                    _curSelectedEvent = newEvent;
                }
            }

            //"Sort"
            if (GUILayout.Button(_editor.GetText(TEXT.DLG_Sort), GUILayout.Width(80), GUILayout.Height(30)))
            {
                apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_SortEvents, _editor, _animClip._portrait, null, false);

                //프레임 순으로 정렬을 한다.
                if (_animClip._animEvents != null)
                {
                    _animClip._animEvents.Sort(delegate(apAnimEvent a, apAnimEvent b)
                    {
                        if (a._frameIndex == b._frameIndex)
                        {
                            return(string.Compare(a._eventName, b._eventName));
                        }
                        return(a._frameIndex - b._frameIndex);
                    });

                    apEditorUtil.SetEditorDirty();
                }
            }
            EditorGUILayout.EndHorizontal();

            //선택된 AnimEvent에 대한 설정을 하자
            GUILayout.Space(5);
            apEditorUtil.GUI_DelimeterBoxH(width - 10);
            GUILayout.Space(5);

            //선택이 안되었다면 더미 데이터로 채워야함
            int    curFrameIndex     = 0;
            int    curFrameIndex_End = 0;
            string curName           = "<None>";

            apAnimEvent.CALL_TYPE           curCallType  = apAnimEvent.CALL_TYPE.Once;
            List <apAnimEvent.SubParameter> curSubParams = null;
            int curNumSubParams = 0;

            bool isSelected = _curSelectedEvent != null && _animClip._animEvents.Contains(_curSelectedEvent);

            if (isSelected)
            {
                curFrameIndex     = _curSelectedEvent._frameIndex;
                curFrameIndex_End = _curSelectedEvent._frameIndex_End;
                curName           = _curSelectedEvent._eventName;
                curCallType       = _curSelectedEvent._callType;
                curSubParams      = _curSelectedEvent._subParams;
                curNumSubParams   = curSubParams.Count;
            }

            if (isSelected)
            {
                GUI.backgroundColor = new Color(0.6f, 0.8f, 0.9f, 1.0f);
            }

            //"(Not Selected)"
            GUILayout.Box((isSelected) ? curName : "(" + _editor.GetText(TEXT.DLG_NotSelected) + ")", guiStyleBox, GUILayout.Width(width - 10), GUILayout.Height(25));

            GUI.backgroundColor = prevColor;

            GUILayout.Space(5);

            EditorGUILayout.BeginVertical(GUILayout.Height(90));
            curName     = EditorGUILayout.DelayedTextField(_editor.GetText(TEXT.DLG_EventName), curName);                      //"Event(Function) Name"
            curCallType = (apAnimEvent.CALL_TYPE)EditorGUILayout.EnumPopup(_editor.GetText(TEXT.DLG_CallMethod), curCallType); //"Call Method"
            if (curCallType == apAnimEvent.CALL_TYPE.Once)
            {
                curFrameIndex = EditorGUILayout.DelayedIntField(_editor.GetText(TEXT.DLG_TargetFrame), curFrameIndex);                //"Target Frame"
            }
            else
            {
                curFrameIndex     = EditorGUILayout.DelayedIntField(_editor.GetText(TEXT.DLG_StartFrame), curFrameIndex);            //"Start Frame"
                curFrameIndex_End = EditorGUILayout.DelayedIntField(_editor.GetText(TEXT.DLG_EndFrame), curFrameIndex_End);          //"End Frame"
            }
            EditorGUILayout.EndVertical();

            GUILayout.Space(5);
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Parameters));            //"Parameters"
            GUILayout.Space(5);


            GUI.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
            GUI.Box(new Rect(0, (height - (bottomHeight - 171)) + 22, width, 100), "");
            GUI.backgroundColor = prevColor;

            if (!isSelected)
            {
                if (!isGUIEvent)
                {
                    curNumSubParams = _prevNumSubParams;
                }
            }

            _scrollList_Param = EditorGUILayout.BeginScrollView(_scrollList_Param, GUILayout.Width(width), GUILayout.Height(100));

            GUILayout.Space(5);
            int valueWidth     = width - (10 + 35 + 130 + 36 + 36 + 36 + 20);
            int valueHalfWidth = ((valueWidth / 2) - 10);
            int midWaveWidth   = 20;

            valueWidth += 7;

            GUIStyle guiStyleListBtn = new GUIStyle(GUI.skin.button);

            guiStyleListBtn.margin = GUI.skin.textField.margin;

            apAnimEvent.SubParameter targetSubParam = null;
            bool isLayerUp     = false;
            bool isLayerDown   = false;
            bool isRemoveParam = false;

            //SubParam 리스트를 출력하자
            if (curNumSubParams > 0)
            {
                if (isSelected && curSubParams != null && curSubParams.Count == curNumSubParams)
                {
                    for (int i = 0; i < curNumSubParams; i++)
                    {
                        EditorGUILayout.BeginHorizontal(GUILayout.Width(width - 50), GUILayout.Height(24));
                        GUILayout.Space(15);
                        GUILayout.Label("[" + i + "]", GUILayout.Width(30), GUILayout.Height(20));

                        curSubParams[i]._paramType = (apAnimEvent.PARAM_TYPE)EditorGUILayout.EnumPopup(curSubParams[i]._paramType, GUILayout.Width(120), GUILayout.Height(20));

                        switch (curSubParams[i]._paramType)
                        {
                        case apAnimEvent.PARAM_TYPE.Bool:
                        {
                            bool nextValue = EditorGUILayout.Toggle(curSubParams[i]._boolValue, GUILayout.Width(valueWidth));

                            if (curSubParams[i]._boolValue != nextValue)
                            {
                                apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                curSubParams[i]._boolValue = nextValue;
                            }
                        }
                        break;

                        case apAnimEvent.PARAM_TYPE.Integer:
                        {
                            if (curCallType == apAnimEvent.CALL_TYPE.Once)
                            {
                                int nextValue = EditorGUILayout.DelayedIntField(curSubParams[i]._intValue, GUILayout.Width(valueWidth));

                                if (curSubParams[i]._intValue != nextValue)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                    curSubParams[i]._intValue = nextValue;
                                }
                            }
                            else
                            {
                                int nextValue_Prev = EditorGUILayout.DelayedIntField(curSubParams[i]._intValue, GUILayout.Width(valueHalfWidth));
                                EditorGUILayout.LabelField(" ~ ", GUILayout.Width(midWaveWidth));
                                int nextValue_Next = EditorGUILayout.DelayedIntField(curSubParams[i]._intValue_End, GUILayout.Width(valueHalfWidth));

                                if (curSubParams[i]._intValue != nextValue_Prev ||
                                    curSubParams[i]._intValue_End != nextValue_Next)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                    curSubParams[i]._intValue     = nextValue_Prev;
                                    curSubParams[i]._intValue_End = nextValue_Next;
                                }
                            }
                        }
                        break;

                        case apAnimEvent.PARAM_TYPE.Float:
                        {
                            if (curCallType == apAnimEvent.CALL_TYPE.Once)
                            {
                                float nextValue = EditorGUILayout.DelayedFloatField(curSubParams[i]._floatValue, GUILayout.Width(valueWidth));
                                if (curSubParams[i]._floatValue != nextValue)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                    curSubParams[i]._floatValue = nextValue;
                                }
                            }
                            else
                            {
                                float nextValue_Prev = EditorGUILayout.DelayedFloatField(curSubParams[i]._floatValue, GUILayout.Width(valueHalfWidth));
                                EditorGUILayout.LabelField(" ~ ", GUILayout.Width(midWaveWidth));
                                float nextVelue_Next = EditorGUILayout.DelayedFloatField(curSubParams[i]._floatValue_End, GUILayout.Width(valueHalfWidth));

                                if (curSubParams[i]._floatValue != nextValue_Prev ||
                                    curSubParams[i]._floatValue_End != nextVelue_Next)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);

                                    curSubParams[i]._floatValue     = nextValue_Prev;
                                    curSubParams[i]._floatValue_End = nextVelue_Next;
                                }
                            }
                        }
                        break;

                        case apAnimEvent.PARAM_TYPE.Vector2:
                        {
                            if (curCallType == apAnimEvent.CALL_TYPE.Once)
                            {
                                Vector2 nextValue = apEditorUtil.DelayedVector2Field(curSubParams[i]._vec2Value, valueWidth);
                                if (curSubParams[i]._vec2Value.x != nextValue.x ||
                                    curSubParams[i]._vec2Value.y != nextValue.y)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                    curSubParams[i]._vec2Value = nextValue;
                                }
                            }
                            else
                            {
                                Vector2 nextValue_Prev = apEditorUtil.DelayedVector2Field(curSubParams[i]._vec2Value, valueHalfWidth);
                                EditorGUILayout.LabelField(" ~ ", GUILayout.Width(midWaveWidth));
                                Vector2 nextValue_Next = apEditorUtil.DelayedVector2Field(curSubParams[i]._vec2Value_End, valueHalfWidth);


                                if (curSubParams[i]._vec2Value.x != nextValue_Prev.x ||
                                    curSubParams[i]._vec2Value.y != nextValue_Prev.y ||
                                    curSubParams[i]._vec2Value_End.x != nextValue_Next.x ||
                                    curSubParams[i]._vec2Value_End.y != nextValue_Next.y)
                                {
                                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);

                                    curSubParams[i]._vec2Value     = nextValue_Prev;
                                    curSubParams[i]._vec2Value_End = nextValue_Next;
                                }
                            }
                        }
                        break;

                        case apAnimEvent.PARAM_TYPE.String:
                        {
                            string nextValue = EditorGUILayout.DelayedTextField(curSubParams[i]._strValue, GUILayout.Width(valueWidth));
                            if (!string.Equals(curSubParams[i]._strValue, nextValue))
                            {
                                apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                                curSubParams[i]._strValue = nextValue;
                            }
                        }
                        break;
                        }

                        if (GUILayout.Button(iconImageLayerUp, guiStyleListBtn, GUILayout.Width(30), GUILayout.Height(20)))
                        {
                            targetSubParam = curSubParams[i];
                            isLayerUp      = true;
                        }
                        if (GUILayout.Button(iconImageLayerDown, guiStyleListBtn, GUILayout.Width(30), GUILayout.Height(20)))
                        {
                            targetSubParam = curSubParams[i];
                            isLayerDown    = true;
                        }
                        if (GUILayout.Button(iconImageRemove, guiStyleListBtn, GUILayout.Width(30), GUILayout.Height(20)))
                        {
                            targetSubParam = curSubParams[i];
                            isRemoveParam  = true;
                        }


                        EditorGUILayout.EndHorizontal();
                    }
                }
                else
                {
                    for (int i = 0; i < curNumSubParams; i++)
                    {
                        EditorGUILayout.BeginHorizontal(GUILayout.Width(width - 50));
                        GUILayout.Space(15);
                        EditorGUILayout.EndHorizontal();
                    }
                }
            }
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width - 50));
            GUILayout.Space(15);

            //변경
            if (_guiContent_AddParameter == null)
            {
                _guiContent_AddParameter = new apGUIContentWrapper();
                _guiContent_AddParameter.ClearText(false);
                _guiContent_AddParameter.AppendSpaceText(1, false);
                _guiContent_AddParameter.AppendText(_editor.GetText(TEXT.DLG_AddParameter), true);

                _guiContent_AddParameter.SetImage(iconImageAddParam);
            }

            if (isSelected)
            {
                //" Add Parameter"
                if (GUILayout.Button(_guiContent_AddParameter.Content, guiStyle_None, GUILayout.Height(20)))
                {
                    if (isSelected && curSubParams != null && curSubParams.Count == curNumSubParams)
                    {
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);

                        curSubParams.Add(new apAnimEvent.SubParameter());
                    }
                }
            }
            else
            {
                if (GUILayout.Button(apEditorUtil.Text_EMPTY, guiStyle_None, GUILayout.Height(20)))
                {
                    //Nooo..
                }
            }
            EditorGUILayout.EndHorizontal();



            GUILayout.Space(150);

            EditorGUILayout.EndScrollView();

            GUILayout.Space(10);

            EditorGUILayout.BeginVertical(GUILayout.Width(width), GUILayout.Height(40));
            if (isSelected)
            {
                //"Remove Event [" + curName + "]"
                if (GUILayout.Button(string.Format("{0} [{1}]", _editor.GetText(TEXT.DLG_RemoveEvent), curName), GUILayout.Height(20)))
                {
                    if (_curSelectedEvent != null && _animClip._animEvents.Contains(_curSelectedEvent))
                    {
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_RemoveEvent, _editor, _animClip._portrait, null, false);
                        _animClip._animEvents.Remove(_curSelectedEvent);

                        _curSelectedEvent = null;
                        isSelected        = false;
                    }
                }
            }
            else
            {
                if (GUILayout.Button("", guiStyle_None, GUILayout.Height(20)))
                {
                }
            }
            EditorGUILayout.EndVertical();



            if (isSelected && _curSelectedEvent != null)
            {
                //순서를 바꾸거나 SubParam을 삭제하는 요청이 있으면 처리해주자
                if (targetSubParam != null && _curSelectedEvent._subParams.Contains(targetSubParam))
                {
                    if (isLayerUp)
                    {
                        //Index -1

                        int index = _curSelectedEvent._subParams.IndexOf(targetSubParam);
                        if (index > 0)
                        {
                            apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                            _curSelectedEvent._subParams.Remove(targetSubParam);
                            _curSelectedEvent._subParams.Insert(index - 1, targetSubParam);
                        }
                    }
                    else if (isLayerDown)
                    {
                        //Index +1
                        int index = _curSelectedEvent._subParams.IndexOf(targetSubParam);
                        if (index < _curSelectedEvent._subParams.Count - 1)
                        {
                            apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                            _curSelectedEvent._subParams.Remove(targetSubParam);
                            _curSelectedEvent._subParams.Insert(index + 1, targetSubParam);
                        }
                    }
                    else if (isRemoveParam)
                    {
                        //삭제한다.
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);
                        _curSelectedEvent._subParams.Remove(targetSubParam);
                    }
                }


                if (_curSelectedEvent._frameIndex != curFrameIndex ||
                    _curSelectedEvent._frameIndex_End != curFrameIndex_End ||
                    _curSelectedEvent._eventName != curName ||
                    _curSelectedEvent._callType != curCallType)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Anim_EventChanged, _editor, _animClip._portrait, null, false);

                    _curSelectedEvent._frameIndex     = curFrameIndex;
                    _curSelectedEvent._frameIndex_End = curFrameIndex_End;
                    _curSelectedEvent._eventName      = curName;
                    _curSelectedEvent._callType       = curCallType;
                }
            }


            EditorGUILayout.BeginHorizontal();
            bool isClose = false;

            //"Close"
            if (GUILayout.Button(_editor.GetText(TEXT.DLG_Close), GUILayout.Height(30)))
            {
                isClose = true;
                apEditorUtil.ReleaseGUIFocus();
            }
            EditorGUILayout.EndHorizontal();


            if (isGUIEvent)
            {
                _prevNumSubParams = curNumSubParams;
            }

            if (isClose)
            {
                CloseDialog();
            }
        }
        // Opt용 Update / Opt 플레이 제어
        //---------------------------------------------
        // Opt용 Update 함수들은 "플레이 상태"의 영향을 받지 않는다.
        // AnimPlayUnit에 래핑된 상태이므로 모든 제어에 대해서 바로 처리한다.
        // Editor와 달리 "실수형 CurFrame"을 이용하며, Reverse 처리도 가능하다
        // MeshGroup과 ControlParam을 직접 제어하진 않는다. (AnimPlayUnit이 한다)

        /// <summary>
        /// [Opt 실행] Delta만큼 업데이트를 한다.
        /// Keyframe Weight와 Control Param Result를 만든다.
        /// </summary>
        /// <param name="tDelta">재생 시간. 음수면 Reverse가 된다.</param>
        /// <returns>Update가 종료시 True, 그 외에는 False이다.</returns>
        public bool Update_Opt(float tDelta)
        {
            _tUpdate      += tDelta;
            _tUpdateTotal += tDelta;
            bool isEnd = false;

            if (tDelta > 0)
            {
                //Speed Ratio가 크면 프레임이 한번에 여러개 이동할 수 있다.
                while (_tUpdate > TimePerFrame)
                {
                    //프레임이 증가한다.
                    _curFrame++;
                    _tUpdate -= TimePerFrame;

                    if (_curFrame >= _endFrame)
                    {
                        if (_isLoop)
                        {
                            //루프일 경우 -> 첫 프레임으로 돌아간다.
                            _curFrame      = _startFrame;
                            _tUpdateTotal -= TimeLength;

                            //Animation 이벤트도 리셋한다.
                            if (_animEvents != null && _animEvents.Count > 0)
                            {
                                for (int i = 0; i < _animEvents.Count; i++)
                                {
                                    _animEvents[i].ResetCallFlag();
                                }
                            }
                        }
                        else
                        {
                            //루프가 아닐 경우
                            _curFrame     = _endFrame;
                            _tUpdate      = 0.0f;
                            _tUpdateTotal = TimeLength;
                            isEnd         = true;
                            break;
                        }
                    }

                    //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod);
                }
            }
            else if (tDelta < 0)
            {
                while (_tUpdate < 0.0f)
                {
                    //프레임이 감소한다.
                    _curFrame--;
                    _tUpdate += TimePerFrame;

                    if (_curFrame <= _startFrame)
                    {
                        if (_isLoop)
                        {
                            //루프일 경우 -> 마지막 프레임으로 돌아간다.
                            _curFrame      = _endFrame;
                            _tUpdateTotal += TimeLength;

                            //Animation 이벤트도 리셋한다.
                            if (_animEvents != null && _animEvents.Count > 0)
                            {
                                for (int i = 0; i < _animEvents.Count; i++)
                                {
                                    _animEvents[i].ResetCallFlag();
                                }
                            }
                        }
                        else
                        {
                            //루프가 아닐 경우
                            _curFrame     = _startFrame;
                            _tUpdate      = 0.0f;
                            _tUpdateTotal = 0.0f;
                            isEnd         = true;
                            break;
                        }
                    }

                    //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod);
                }
            }

            float unitWeight = _parentPlayUnit.UnitWeight;

            //이거 문제 생기면 끈다.
            //if (_parentPlayUnit._playOrder == 0)
            //{
            //	unitWeight = 1.0f;
            //}
            //??이거요?

            //UpdateControlParam(false, _parentPlayUnit._layer, _parentPlayUnit.UnitWeight, _parentPlayUnit.BlendMethod);
            UpdateControlParam(false, _parentPlayUnit._layer, unitWeight, _parentPlayUnit.BlendMethod);

            //추가
            //AnimEvent도 업데이트 하자
            if (_animEvents != null && _animEvents.Count > 0)
            {
                apAnimEvent animEvent = null;
                for (int i = 0; i < _animEvents.Count; i++)
                {
                    animEvent = _animEvents[i];
                    animEvent.Calculate(CurFrameFloat, CurFrame, (tDelta > 0.0f));
                    if (animEvent.IsEventCallable())
                    {
                        if (_portrait._optAnimEventListener != null)
                        {
                            //애니메이션 이벤트를 호출해줍시다.
                            _portrait._optAnimEventListener.SendMessage(animEvent._eventName, animEvent.GetCalculatedParam(), SendMessageOptions.DontRequireReceiver);
                            //UnityEngine.Debug.Log("Animation Event : " + animEvent._eventName);
                        }
                    }
                }
            }

            //if (isEnd)
            //{
            //	//Animation 이벤트도 리셋한다.
            //	if (_animEvents != null && _animEvents.Count > 0)
            //	{
            //		for (int i = 0; i < _animEvents.Count; i++)
            //		{
            //			_animEvents[i].ResetCallFlag();
            //		}
            //	}
            //}

            return(isEnd);
        }
        // 변경 1.17 : 메카님은 다르게 처리해야한다.
        public bool UpdateMecanim_Opt(float tDelta, float stateSpeed)
        {
            _tUpdate      += tDelta;
            _tUpdateTotal += tDelta;
            bool isEnd = false;


            if (tDelta > 0)
            {
                //Speed Ratio가 크면 프레임이 한번에 여러개 이동할 수 있다.
                while (_tUpdate > TimePerFrame)
                {
                    //프레임이 증가한다.
                    _curFrame++;
                    _tUpdate -= TimePerFrame;

                    if (_curFrame >= _endFrame)
                    {
                        if (_isLoop)
                        {
                            //루프일 경우 -> 첫 프레임으로 돌아간다.
                            _curFrame      = _startFrame;
                            _tUpdateTotal -= TimeLength;

                            if (stateSpeed > 0.0f)
                            {
                                //UnityEngine.Debug.LogWarning("Frame Over the Length (Forward)");
                                //만약 밖에서 이벤트 초기화가 안되었다면 여기서 하자
                                ResetEvents();
                            }
                        }
                        else
                        {
                            //루프가 아닐 경우
                            _curFrame     = _endFrame;
                            _tUpdate      = 0.0f;
                            _tUpdateTotal = TimeLength;
                            isEnd         = true;
                            break;
                        }
                    }
                }
            }
            else if (tDelta < 0)
            {
                while (_tUpdate < 0.0f)
                {
                    //프레임이 감소한다.
                    _curFrame--;
                    _tUpdate += TimePerFrame;

                    if (_curFrame <= _startFrame)
                    {
                        if (_isLoop)
                        {
                            //루프일 경우 -> 마지막 프레임으로 돌아간다.
                            _curFrame      = _endFrame;
                            _tUpdateTotal += TimeLength;

                            if (stateSpeed < 0.0f)
                            {
                                //UnityEngine.Debug.LogWarning("Frame Over the Length (Backward)");
                                //만약 밖에서 이벤트 초기화가 안되었다면 여기서 하자
                                ResetEvents();
                            }
                        }
                        else
                        {
                            //루프가 아닐 경우
                            _curFrame     = _startFrame;
                            _tUpdate      = 0.0f;
                            _tUpdateTotal = 0.0f;
                            isEnd         = true;
                            break;
                        }
                    }
                }
            }

#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                if (_parentPlayUnit == null)
                {
                    return(true);
                }
            }
#endif

            float unitWeight = _parentPlayUnit.UnitWeight;

            UpdateControlParam(false, _parentPlayUnit._layer, unitWeight, _parentPlayUnit.BlendMethod);

            //추가
            //AnimEvent도 업데이트 하자
            if (_animEvents != null && _animEvents.Count > 0)
            {
                apAnimEvent animEvent = null;
                for (int i = 0; i < _animEvents.Count; i++)
                {
                    animEvent = _animEvents[i];
                    //animEvent.Calculate(CurFrameFloat, CurFrame, (tDelta > 0.0f), Mathf.Abs(tDelta) > 0.0001f, tDelta, _speedRatio);//기존
                    animEvent.Calculate(CurFrameFloat, CurFrame, (stateSpeed > 0.0f), Mathf.Abs(tDelta) > 0.0001f, tDelta, stateSpeed);                    //메카님용
                    if (animEvent.IsEventCallable())
                    {
                        if (_portrait._optAnimEventListener != null)
                        {
                            //애니메이션 이벤트를 호출해줍시다.
                            //UnityEngine.Debug.Log("Animation Event : " + animEvent._eventName + " / CurFrameFloat : " + CurFrameFloat + " / tDelta : " + tDelta);
                            _portrait._optAnimEventListener.SendMessage(animEvent._eventName, animEvent.GetCalculatedParam(), SendMessageOptions.DontRequireReceiver);
                        }
                    }
                }
            }

            return(isEnd);
        }