Exemplo n.º 1
0
 /// <summary>
 /// 처리 후 재배치를 한다.
 /// RootUnit이 재활용이 "안된" 경우에 이 함수를 호출한다.
 /// Unlink 그룹으로 옮길 것을 옮겨준다.
 /// </summary>
 /// <param name="group1_Recycled"></param>
 /// <param name="group2_Remove"></param>
 /// <param name="group3_Unlinked"></param>
 public void SetHierarchyToUnlink(GameObject group3_Unlinked, apBakeResult bakeResult)
 {
     //재활용되지 않은 GameObject들을 적절히 나누어서 배치한다.
     //재귀적으로 호출한다.
     if (_rootParam == null)
     {
         return;
     }
     SetHierarchyToUnlinkRecursive(_rootParam, group3_Unlinked, bakeResult);
 }
Exemplo n.º 2
0
        private void SetHierarchyForceRecursive(apBakeLinkParam targetLinkParam, GameObject parentGameObject, apBakeResult bakeResult, bool isAddToRelink)
        {
            if (!targetLinkParam._isRecycled)
            {
                targetLinkParam._prevGameObject.transform.parent = parentGameObject.transform;
                targetLinkParam._isReGroupCompleted = true;

                //Bake Result도 추가
                if (isAddToRelink)
                {
                    //Count+1 : Relink
                    bakeResult.Add_ReLinkedExternalObject(targetLinkParam._prevGameObject.name);
                }
                else
                {
                    //Count+1 : Unlink
                    bakeResult.Add_UnlinkedExternalObject(targetLinkParam._prevGameObject.name);
                }
            }

            if (targetLinkParam._childLinkParams != null)
            {
                for (int i = 0; i < targetLinkParam._childLinkParams.Count; i++)
                {
                    SetHierarchyForceRecursive(targetLinkParam._childLinkParams[i], targetLinkParam._prevGameObject, bakeResult, isAddToRelink);
                }
            }
        }
Exemplo n.º 3
0
        private void SetHierarchyToUnlinkRecursive(apBakeLinkParam targetLinkParam, GameObject group3_Unlinked, apBakeResult bakeResult)
        {
            //재활용되지 않은 GameObject들을 적절히 나누어서 배치한다. (모두 Recycle은 안되었을 것)
            //재귀적으로 호출한다.
            bool isChildCall = true;

            if (!targetLinkParam._isReGroupCompleted)
            {
                //재활용 안된거 발견
                if (targetLinkParam._isOptGameObject)
                {
                    //1. OptGameObject인데 재활용이 안되었다.
                    //-> 컴포넌트 상태에 따라 [삭제 예정] 그룹에 넣을지 [링크 깨짐] 그룹에 넣을지 결정
                    if (targetLinkParam._isOtherComponentExist)
                    {
                        //알 수 없는 컴포넌트 -> 링크 깨짐 그룹
                        targetLinkParam._prevGameObject.transform.parent = group3_Unlinked.transform;

                        bakeResult.Add_UnlinkedExternalObject(targetLinkParam._prevGameObject.name);
                    }
                    else
                    {
                        //걍 재활용 실패 -> 삭제 예정
                        //따로 처리는 안합니더
                        //targetLinkParam._prevGameObject.transform.parent = group2_Remove.transform;
                    }

                    targetLinkParam._isReGroupCompleted = true;                    //재배치 끝
                }
                else
                {
                    //2. OptGameObject가 아니다.
                    //Parent가 재활용에 성공할 리가 없으므로
                    //그냥 무조건 Unlink로 연결
                    SetHierarchyForceRecursive(targetLinkParam, group3_Unlinked, bakeResult, false);
                    targetLinkParam._isReGroupCompleted = true; //재배치 끝
                    isChildCall = false;                        //자식 객체로의 호출은 더이상 네이버
                }
            }

            if (isChildCall)
            {
                //자식 객체들도 넣어주자
                if (targetLinkParam._childLinkParams != null)
                {
                    for (int i = 0; i < targetLinkParam._childLinkParams.Count; i++)
                    {
                        SetHierarchyToUnlinkRecursive(targetLinkParam._childLinkParams[i], group3_Unlinked, bakeResult);
                    }
                }
            }
        }
Exemplo n.º 4
0
        private void SetHierarchyNotRecycledObjectsRecursive(apBakeLinkParam targetLinkParam, GameObject group1_Recycled, GameObject group2_Remove, GameObject group3_Unlinked, apBakeResult bakeResult)
        {
            //재활용되지 않은 GameObject들을 적절히 나누어서 배치한다.
            //재귀적으로 호출한다.
            bool isChildCall = true;

            if (!targetLinkParam._isRecycled && !targetLinkParam._isReGroupCompleted)
            {
                //재활용 안된거 발견
                if (targetLinkParam._isOptGameObject)
                {
                    //1. OptGameObject인데 재활용이 안되었다.
                    //-> 컴포넌트 상태에 따라 [삭제 예정] 그룹에 넣을지 [링크 깨짐] 그룹에 넣을지 결정
                    if (targetLinkParam._isOtherComponentExist)
                    {
                        //알 수 없는 컴포넌트 -> 링크 깨짐 그룹
                        targetLinkParam._prevGameObject.transform.parent = group3_Unlinked.transform;

                        //Count+1 : Unlink
                        bakeResult.Add_UnlinkedExternalObject(targetLinkParam._prevGameObject.name);
                    }
                    else
                    {
                        //걍 재활용 실패 -> 삭제 예정
                        targetLinkParam._prevGameObject.transform.parent = group2_Remove.transform;

                        //Count+1 : Removed
                        bakeResult.AddCount_RemovedOptGameObject();
                    }

                    targetLinkParam._isReGroupCompleted = true;                    //재배치 끝
                }
                else
                {
                    //2. OptGameObject가 아니다.
                    //-> 음.. 뭘 참조하고 있었을까요..
                    //참조는 모르겠고 하이라키만 맞춰줍시다.
                    //Parent가 있을때 + 해당 Parent가 Opt이며 + 재활용에 성공했을 경우에 한해서 재연결을 해준다.
                    //재연결에 성공한 경우 -> Child Transform들을 재귀적으로 다시 연결해준다. (조건 안봄)
                    //그 외에는 [링크 깨짐] 그룹에 넣는다.

                    if (targetLinkParam._parentLinkParam != null &&
                        targetLinkParam._parentLinkParam._isOptGameObject &&
                        targetLinkParam._parentLinkParam._isRecycled)
                    {
                        targetLinkParam._isReGroupCompleted = true;                        //재배치 끝
                        SetHierarchyForceRecursive(targetLinkParam, targetLinkParam._parentLinkParam._prevGameObject, bakeResult, true);
                        isChildCall = false;
                    }
                    else
                    {
                        targetLinkParam._prevGameObject.transform.parent = group3_Unlinked.transform;
                        targetLinkParam._isReGroupCompleted = true;                        //재배치 끝
                    }
                }
            }

            //자식 객체들도 넣어주자
            if (isChildCall)
            {
                if (targetLinkParam._childLinkParams != null)
                {
                    for (int i = 0; i < targetLinkParam._childLinkParams.Count; i++)
                    {
                        SetHierarchyNotRecycledObjectsRecursive(targetLinkParam._childLinkParams[i], group1_Recycled, group2_Remove, group3_Unlinked, bakeResult);
                    }
                }
            }
        }
Exemplo n.º 5
0
        //public void PrintTimes()
        //{
        //	Debug.LogError("----------------------------------------------------------------");
        //	Debug.Log("Opt Transform [" + _timerCalls[TIMER_TYPE.OptTransform] + "] : " + _stopwatches[TIMER_TYPE.OptTransform].Elapsed.TotalSeconds);
        //	Debug.Log("Opt Mesh [" + _timerCalls[TIMER_TYPE.OptMesh] + "] : " + _stopwatches[TIMER_TYPE.OptMesh].Elapsed.TotalSeconds);
        //	Debug.Log("Opt Bone [" + _timerCalls[TIMER_TYPE.OptBone] + "] : " + _stopwatches[TIMER_TYPE.OptBone].Elapsed.TotalSeconds);
        //	Debug.Log("Opt Node [" + _timerCalls[TIMER_TYPE.OptNode] + "] : " + _stopwatches[TIMER_TYPE.OptNode].Elapsed.TotalSeconds);
        //	Debug.LogError("----------------------------------------------------------------");

        //}


        /// <summary>
        /// 처리 후 재배치를 한다.
        /// RootUnit이 재활용된 경우에는 이 함수를 호출한다.
        /// </summary>
        /// <param name="group1_Recycled"></param>
        /// <param name="group2_Remove"></param>
        /// <param name="group3_Unlinked"></param>
        public void SetHierarchyNotRecycledObjects(GameObject group1_Recycled, GameObject group2_Remove, GameObject group3_Unlinked, apBakeResult bakeResult)
        {
            //재활용되지 않은 GameObject들을 적절히 나누어서 배치한다.
            //재귀적으로 호출한다.
            if (_rootParam == null)
            {
                return;
            }
            SetHierarchyNotRecycledObjectsRecursive(_rootParam, group1_Recycled, group2_Remove, group3_Unlinked, bakeResult);
        }
        // GUI
        //------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

            if (_editor == null || _targetPortrait == null)
            {
                CloseDialog();
                return;
            }

            //만약 Portriat가 바뀌었거나 Editor가 리셋되면 닫자
            if (_editor != apEditor.CurrentEditor || _targetPortrait != apEditor.CurrentEditor._portrait)
            {
                CloseDialog();
                return;
            }



            //Sorting Layer를 추가하자
            if (_sortingLayerNames == null || _sortingLayerIDs == null)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }
            else if (_sortingLayerNames.Length != SortingLayer.layers.Length ||
                     _sortingLayerIDs.Length != SortingLayer.layers.Length)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }

            for (int i = 0; i < SortingLayer.layers.Length; i++)
            {
                _sortingLayerNames[i] = SortingLayer.layers[i].name;
                _sortingLayerIDs[i]   = SortingLayer.layers[i].id;
            }


            int width_2Btn = (width - 14) / 2;

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Bake), _tab == TAB.Bake, width_2Btn, 25))
            {
                _tab = TAB.Bake;
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Setting), _tab == TAB.Options, width_2Btn, 25))
            {
                _tab = TAB.Options;
            }
            EditorGUILayout.EndHorizontal();


            if (_tab == TAB.Bake)
            {
                GUILayout.Space(5);

                // 1. Bake에 대한 UI
                //Bake 설정
                //EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_BakeSetting));//"Bake Setting"
                //GUILayout.Space(5);

                EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Portrait), _targetPortrait, typeof(apPortrait), true);                //"Portait"

                GUILayout.Space(5);

                //"Bake Scale"
                float prevBakeScale = _targetPortrait._bakeScale;
                _targetPortrait._bakeScale = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_BakeScale), _targetPortrait._bakeScale);

                //"Z Per Depth"
                float prevBakeZSize = _targetPortrait._bakeZSize;
                _targetPortrait._bakeZSize = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_ZPerDepth), _targetPortrait._bakeZSize);

                if (_targetPortrait._bakeZSize < 0.5f)
                {
                    _targetPortrait._bakeZSize = 0.5f;
                }

                if (prevBakeScale != _targetPortrait._bakeScale ||
                    prevBakeZSize != _targetPortrait._bakeZSize)
                {
                    apEditorUtil.SetEditorDirty();
                }


                //Bake 버튼
                GUILayout.Space(10);
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Bake), GUILayout.Height(45)))                //"Bake"
                {
                    GUI.FocusControl(null);

                    //CheckChangedProperties(nextRootScale, nextZScale);
                    apEditorUtil.SetEditorDirty();

                    //-------------------------------------
                    // Bake 함수를 실행한다. << 중요오오오오
                    //-------------------------------------

                    apBakeResult bakeResult = _editor.Controller.Bake();


                    _editor.Notification("[" + _targetPortrait.name + "] is Baked", false, false);

                    if (bakeResult.NumUnlinkedExternalObject > 0)
                    {
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                    _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                    _editor.GetText(TEXT.Okay));
                    }

                    //추가 3.29 : Bake 후에 Ambient를 체크하자
                    CheckAmbientAndCorrection();
                }

                GUILayout.Space(10);
                apEditorUtil.GUI_DelimeterBoxH(width - 10);
                GUILayout.Space(10);


                //최적화 Bake
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_OptimizedBaking));                //"Optimized Baking"

                //"Target"
                apPortrait nextOptPortrait = (apPortrait)EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Target), _targetPortrait._bakeTargetOptPortrait, typeof(apPortrait), true);

                if (nextOptPortrait != _targetPortrait._bakeTargetOptPortrait)
                {
                    //타겟을 바꾸었다.
                    bool isChanged = false;
                    if (nextOptPortrait != null)
                    {
                        //1. 다른 Portrait를 선택했다.
                        if (!nextOptPortrait._isOptimizedPortrait)
                        {
                            //1-1. 최적화된 객체가 아니다.
                            EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                        _editor.GetText(TEXT.OptBakeError_NotOptTarget_Body),
                                                        _editor.GetText(TEXT.Close));
                        }
                        else if (nextOptPortrait._bakeSrcEditablePortrait != _targetPortrait)
                        {
                            //1-2. 다른 대상으로부터 Bake된 Portrait같다. (물어보고 계속)
                            bool isResult = EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                                        _editor.GetText(TEXT.OptBakeError_SrcMatchError_Body),
                                                                        _editor.GetText(TEXT.Okay),
                                                                        _editor.GetText(TEXT.Cancel));

                            if (isResult)
                            {
                                //뭐 선택하겠다는데요 뭐..
                                isChanged = true;
                            }
                        }
                        else
                        {
                            //1-3. 오케이. 변경 가능
                            isChanged = true;
                        }
                    }
                    else
                    {
                        //2. 선택을 해제했다.
                        isChanged = true;
                    }

                    if (isChanged)
                    {
                        //Target을 변경한다.
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                        _targetPortrait._bakeTargetOptPortrait = nextOptPortrait;
                    }
                }

                string optBtnText = "";
                if (_targetPortrait._bakeTargetOptPortrait != null)
                {
                    //optBtnText = "Optimized Bake to\n[" + _targetPortrait._bakeTargetOptPortrait.gameObject.name + "]";
                    optBtnText = string.Format("{0}\n[{1}]", _editor.GetText(TEXT.DLG_OptimizedBakeTo), _targetPortrait._bakeTargetOptPortrait.gameObject.name);
                }
                else
                {
                    //optBtnText = "Optimized Bake\n(Make New GameObject)";
                    optBtnText = _editor.GetText(TEXT.DLG_OptimizedBakeMakeNew);
                }
                GUILayout.Space(10);

                if (GUILayout.Button(optBtnText, GUILayout.Height(45)))
                {
                    GUI.FocusControl(null);

                    //CheckChangedProperties(nextRootScale, nextZScale);


                    //Optimized Bake를 하자
                    apBakeResult bakeResult = _editor.Controller.OptimizedBake(_targetPortrait, _targetPortrait._bakeTargetOptPortrait);

                    if (bakeResult.NumUnlinkedExternalObject > 0)
                    {
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                    _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                    _editor.GetText(TEXT.Okay));
                    }

                    _editor.Notification("[" + _targetPortrait.name + "] is Baked (Optimized)", false, false);

                    //추가 3.29 : Bake 후에 Ambient를 체크하자
                    CheckAmbientAndCorrection();
                }
            }
            else
            {
                //Vector2 curScroll = (_tab == TAB.Bake) ? _scroll_Bake : _scroll_Options;

                _scroll_Options = EditorGUILayout.BeginScrollView(_scroll_Options, false, true, GUILayout.Width(width), GUILayout.Height(height - 30));

                EditorGUILayout.BeginVertical(GUILayout.Width(width - 24));
                GUILayout.Space(5);

                width -= 24;

                // 2. Option에 대한 UI
                //1. Gamma Space Space
                bool prevBakeGamma   = _editor._isBakeColorSpaceToGamma;
                int  iPrevColorSpace = prevBakeGamma ? 0 : 1;
                int  iNextColorSpace = EditorGUILayout.Popup(_editor.GetUIWord(UIWORD.ColorSpace), iPrevColorSpace, _colorSpaceNames);
                if (iNextColorSpace != iPrevColorSpace)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (iNextColorSpace == 0)
                    {
                        //Gamma
                        _editor._isBakeColorSpaceToGamma = true;
                    }
                    else
                    {
                        //Linear
                        _editor._isBakeColorSpaceToGamma = false;
                    }
                }

                GUILayout.Space(10);

                //2. Sorting Layer
                int prevSortingLayerID = _editor._portrait._sortingLayerID;
                int prevSortingOrder   = _editor._portrait._sortingOrder;
                apPortrait.SORTING_ORDER_OPTION prevSortingLayerOption = _editor._portrait._sortingOrderOption;

                int layerIndex = -1;
                for (int i = 0; i < SortingLayer.layers.Length; i++)
                {
                    if (SortingLayer.layers[i].id == _editor._portrait._sortingLayerID)
                    {
                        //찾았다.
                        layerIndex = i;
                        break;
                    }
                }
                if (layerIndex < 0)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);

                    //어라 레이어가 없는데용..
                    //초기화해야겠다.
                    _editor._portrait._sortingLayerID = -1;
                    if (SortingLayer.layers.Length > 0)
                    {
                        _editor._portrait._sortingLayerID = SortingLayer.layers[0].id;
                        layerIndex = 0;
                    }
                }
                int nextIndex = EditorGUILayout.Popup(_editor.GetText(TEXT.SortingLayer), layerIndex, _sortingLayerNames);                //"Sorting Layer"
                if (nextIndex != layerIndex)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    //레이어가 변경되었다.
                    if (nextIndex >= 0 && nextIndex < SortingLayer.layers.Length)
                    {
                        //LayerID 변경
                        _editor._portrait._sortingLayerID = SortingLayer.layers[nextIndex].id;
                    }
                }

                //추가 19.8.18 : Sorting Order를 지정하는 방식을 3가지 + 미적용 1가지로 더 세분화
                apPortrait.SORTING_ORDER_OPTION nextSortingLayerOption = (apPortrait.SORTING_ORDER_OPTION)EditorGUILayout.EnumPopup(_editor.GetText(TEXT.SortingOrderOption), _editor._portrait._sortingOrderOption);
                if (nextSortingLayerOption != _editor._portrait._sortingOrderOption)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _editor._portrait._sortingOrderOption = nextSortingLayerOption;
                }

                if (_editor._portrait._sortingOrderOption == apPortrait.SORTING_ORDER_OPTION.SetOrder)
                {
                    //Set Order인 경우에만 한정
                    int nextOrder = EditorGUILayout.IntField(_editor.GetText(TEXT.SortingOrder), _editor._portrait._sortingOrder);                    //"Sorting Order"
                    if (nextOrder != _editor._portrait._sortingOrder)
                    {
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                        _editor._portrait._sortingOrder = nextOrder;
                    }
                }

                GUILayout.Space(10);

                //3. 메카님 사용 여부

                //EditorGUILayout.LabelField("Animation Settings");
                bool   prevIsUsingMecanim = _targetPortrait._isUsingMecanim;
                string prevMecanimPath    = _targetPortrait._mecanimAnimClipResourcePath;
                _targetPortrait._isUsingMecanim = EditorGUILayout.Toggle(_editor.GetText(TEXT.IsMecanimAnimation), _targetPortrait._isUsingMecanim); //"Is Mecanim Animation"
                EditorGUILayout.LabelField(_editor.GetText(TEXT.AnimationClipExportPath));                                                           //"Animation Clip Export Path"

                GUIStyle guiStyle_ChangeBtn = new GUIStyle(GUI.skin.button);
                guiStyle_ChangeBtn.margin = GUI.skin.textField.margin;
                guiStyle_ChangeBtn.border = GUI.skin.textField.border;

                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(20));
                GUILayout.Space(5);
                EditorGUILayout.TextField(_targetPortrait._mecanimAnimClipResourcePath, GUILayout.Width(width - (70 + 15)));
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Change), guiStyle_ChangeBtn, GUILayout.Width(70), GUILayout.Height(18)))
                {
                    string nextPath = EditorUtility.SaveFolderPanel("Select to export animation clips", "", "");
                    if (!string.IsNullOrEmpty(nextPath))
                    {
                        if (apEditorUtil.IsInAssetsFolder(nextPath))
                        {
                            //유효한 폴더인 경우
                            //중요 : 경로가 절대 경로로 찍힌다.
                            //상대 경로로 바꾸자
                            apEditorUtil.PATH_INFO_TYPE pathInfoType = apEditorUtil.GetPathInfo(nextPath);
                            if (pathInfoType == apEditorUtil.PATH_INFO_TYPE.Absolute_InAssetFolder)
                            {
                                //절대 경로 + Asset 폴더 안쪽이라면
                                //Debug.LogError("절대 경로가 리턴 되었다. : " + nextPath);
                                nextPath = apEditorUtil.AbsolutePath2RelativePath(nextPath);
                                //Debug.LogError(">> 상대 경로로 변경 : " + nextPath);
                            }

                            apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_BakeOptionChanged, _editor, _targetPortrait, _targetPortrait, false);

                            _targetPortrait._mecanimAnimClipResourcePath = nextPath;
                        }
                        else
                        {
                            //유효한 폴더가 아닌 경우
                            //EditorUtility.DisplayDialog("Invalid Folder Path", "Invalid Clip Path", "Close");
                            EditorUtility.DisplayDialog(
                                _editor.GetText(TEXT.DLG_AnimClipSavePathValidationError_Title),
                                _editor.GetText(TEXT.DLG_AnimClipSavePathResetError_Body),
                                _editor.GetText(TEXT.Close));
                        }
                    }

                    GUI.FocusControl(null);
                }
                EditorGUILayout.EndHorizontal();



                GUILayout.Space(10);

                if (_guiContent_Setting_IsImportant == null)
                {
                    _guiContent_Setting_IsImportant = apGUIContentWrapper.Make(_editor.GetText(TEXT.DLG_Setting_IsImportant), false, "When this setting is on, it always updates and the physics effect works.");
                }
                if (_guiContent_Setting_FPS == null)
                {
                    _guiContent_Setting_FPS = apGUIContentWrapper.Make(_editor.GetText(TEXT.DLG_Setting_FPS), false, "This setting is used when <Important> is off");
                }



                //4. Important
                //"Is Important"
                bool nextImportant = EditorGUILayout.Toggle(_guiContent_Setting_IsImportant.Content, _targetPortrait._isImportant);
                if (nextImportant != _targetPortrait._isImportant)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._isImportant = nextImportant;
                }

                //"FPS (Important Off)"
                int nextFPS = EditorGUILayout.DelayedIntField(_guiContent_Setting_FPS.Content, _targetPortrait._FPS);
                if (_targetPortrait._FPS != nextFPS)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (nextFPS < 10)
                    {
                        nextFPS = 10;
                    }
                    _targetPortrait._FPS = nextFPS;
                }

                GUILayout.Space(10);

                //5. Billboard + Perspective

                apPortrait.BILLBOARD_TYPE nextBillboardType = (apPortrait.BILLBOARD_TYPE)EditorGUILayout.Popup(_editor.GetText(TEXT.DLG_Billboard), (int)_targetPortrait._billboardType, _billboardTypeNames);
                if (nextBillboardType != _targetPortrait._billboardType)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._billboardType = nextBillboardType;
                }

                //추가 19.9.24 : Billboard인 경우 카메라의 SortMode를 OrthoGraphic으로 강제할지 여부
                if (_targetPortrait._billboardType != apPortrait.BILLBOARD_TYPE.None)
                {
                    GUILayout.Space(2);
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(width));

                    int      width_Value            = 30;
                    int      width_Label            = width - (width_Value + 10);
                    GUIStyle guiStyle_LabelWrapText = new GUIStyle(GUI.skin.label);
                    guiStyle_LabelWrapText.wordWrap = true;

                    GUILayout.Space(5);
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.SetSortMode2Orthographic), guiStyle_LabelWrapText, GUILayout.Width(width_Label));

                    bool nextForceSortModeToOrtho = EditorGUILayout.Toggle(_targetPortrait._isForceCamSortModeToOrthographic, GUILayout.Width(width_Value), GUILayout.Height(20));
                    if (nextForceSortModeToOrtho != _targetPortrait._isForceCamSortModeToOrthographic)
                    {
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                        _targetPortrait._isForceCamSortModeToOrthographic = nextForceSortModeToOrtho;
                    }

                    EditorGUILayout.EndHorizontal();
                }


                GUILayout.Space(10);

                //6. Shadow

                apPortrait.SHADOW_CASTING_MODE nextChastShadows = (apPortrait.SHADOW_CASTING_MODE)EditorGUILayout.EnumPopup(_editor.GetUIWord(UIWORD.CastShadows), _targetPortrait._meshShadowCastingMode);
                bool nextReceiveShaodw = EditorGUILayout.Toggle(_editor.GetUIWord(UIWORD.ReceiveShadows), _targetPortrait._meshReceiveShadow);
                if (nextChastShadows != _targetPortrait._meshShadowCastingMode ||
                    nextReceiveShaodw != _targetPortrait._meshReceiveShadow)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._meshShadowCastingMode = nextChastShadows;
                    _targetPortrait._meshReceiveShadow     = nextReceiveShaodw;
                }

                GUILayout.Space(10);

                //#if UNITY_2018_1_OR_NEWER
                //변경 19.6.22 : LWRP 기능은 삭제
                //Material Library를 열도록 하자
                //>> 다시 변경 19.8.5 : Clipped Mesh 땜시 다시 열자

                //7. LWRP
                //LWRP 쉐이더를 쓸지 여부와 다시 강제로 생성하기 버튼을 만들자. : 이건 2019부터 적용 (그 전에는 SRP용 처리가 안된다.)
#if UNITY_2019_1_OR_NEWER
                bool prevUseLWRP  = _editor._isUseSRP;
                int  iPrevUseLWRP = prevUseLWRP ? 1 : 0;
                int  iNextUseLWRP = EditorGUILayout.Popup(_editor.GetText(TEXT.RenderPipeline), iPrevUseLWRP, _renderPipelineNames);               //"Render Pipeline"
                if (iNextUseLWRP != iPrevUseLWRP)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (iNextUseLWRP == 0)
                    {
                        //사용 안함
                        _editor._isUseSRP = false;
                    }
                    else
                    {
                        //LWRP 사용함
                        _editor._isUseSRP = true;
                    }
                }
                GUILayout.Space(10);
#endif
                //if(GUILayout.Button("Generate Lightweight Shaders"))
                //{
                //	apShaderGenerator shaderGenerator = new apShaderGenerator();
                //	shaderGenerator.GenerateLWRPShaders();
                //}

                //GUILayout.Space(10);
                //#endif

                //8. VR Supported 19.9.24 추가
                //VR Supported
                int iNextVRSupported = EditorGUILayout.Popup(_editor.GetText(TEXT.VROption), (int)_targetPortrait._vrSupportMode, _vrSupportModeLabel);
                if (iNextVRSupported != (int)_targetPortrait._vrSupportMode)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._vrSupportMode = (apPortrait.VR_SUPPORT_MODE)iNextVRSupported;
                }

                if (_targetPortrait._vrSupportMode == apPortrait.VR_SUPPORT_MODE.SingleCamera)
                {
                    //Single Camera인 경우, Clipping Mask의 크기를 결정해야한다.
                    int iNextVRRTSize = EditorGUILayout.Popup(_editor.GetUIWord(UIWORD.MaskTextureSize), (int)_targetPortrait._vrRenderTextureSize, _vrRTSizeLabel);
                    if (iNextVRRTSize != (int)_targetPortrait._vrRenderTextureSize)
                    {
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                        _targetPortrait._vrRenderTextureSize = (apPortrait.VR_RT_SIZE)iNextVRRTSize;
                    }
                }

                GUILayout.Space(10);


                //11.7 추가 : Ambient Light를 검은색으로 만든다.

                if (GUILayout.Button(_editor.GetText(TEXT.DLG_AmbientToBlack), GUILayout.Height(20)))
                {
                    MakeAmbientLightToBlack();
                }

                //CheckChangedProperties(nextRootScale, nextZScale);
                if (prevSortingLayerID != _editor._portrait._sortingLayerID ||
                    prevSortingOrder != _editor._portrait._sortingOrder ||
                    prevSortingLayerOption != _editor._portrait._sortingOrderOption ||
                    prevIsUsingMecanim != _targetPortrait._isUsingMecanim ||
                    !string.Equals(prevMecanimPath, _targetPortrait._mecanimAnimClipResourcePath) ||
                    prevBakeGamma != _editor._isBakeColorSpaceToGamma
#if UNITY_2019_1_OR_NEWER
                    || prevUseLWRP != _editor._isUseSRP
#endif
                    )
                {
                    apEditorUtil.SetEditorDirty();
                    _editor.SaveEditorPref();
                }

                GUILayout.Space(height + 500);
                EditorGUILayout.EndVertical();

                EditorGUILayout.EndScrollView();
            }

            GUILayout.Space(5);
        }
        // GUI
        //------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

            if (_editor == null || _targetPortrait == null)
            {
                CloseDialog();
                return;
            }

            //만약 Portriat가 바뀌었거나 Editor가 리셋되면 닫자
            if (_editor != apEditor.CurrentEditor || _targetPortrait != apEditor.CurrentEditor._portrait)
            {
                CloseDialog();
                return;
            }

            //Sorting Layer를 추가하자
            if (_sortingLayerNames == null || _sortingLayerIDs == null)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }
            else if (_sortingLayerNames.Length != SortingLayer.layers.Length ||
                     _sortingLayerIDs.Length != SortingLayer.layers.Length)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }

            for (int i = 0; i < SortingLayer.layers.Length; i++)
            {
                _sortingLayerNames[i] = SortingLayer.layers[i].name;
                _sortingLayerIDs[i]   = SortingLayer.layers[i].id;
            }


            //Bake 설정
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_BakeSetting));            //"Bake Setting"
            GUILayout.Space(5);

            EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Portrait), _targetPortrait, typeof(apPortrait), true);            //"Portait"

            GUILayout.Space(5);

            //"Bake Scale"
            float prevBakeScale = _targetPortrait._bakeScale;

            _targetPortrait._bakeScale = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_BakeScale), _targetPortrait._bakeScale);



            //"Z Per Depth"
            float prevBakeZSize = _targetPortrait._bakeZSize;

            _targetPortrait._bakeZSize = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_ZPerDepth), _targetPortrait._bakeZSize);


            if (_targetPortrait._bakeZSize < 0.5f)
            {
                _targetPortrait._bakeZSize = 0.5f;
            }

            GUILayout.Space(5);



            //Gamma Space Space
            bool prevBakeGamma   = _editor._isBakeColorSpaceToGamma;
            int  iPrevColorSpace = prevBakeGamma ? 0 : 1;
            int  iNextColorSpace = EditorGUILayout.Popup(_editor.GetUIWord(UIWORD.ColorSpace), iPrevColorSpace, _colorSpaceNames);

            if (iNextColorSpace != iPrevColorSpace)
            {
                if (iNextColorSpace == 0)
                {
                    //Gamma
                    _editor._isBakeColorSpaceToGamma = true;
                }
                else
                {
                    //Linear
                    _editor._isBakeColorSpaceToGamma = false;
                }
            }
            //_editor._isBakeColorSpaceToGamma = EditorGUILayout.Toggle("Gamma Color Space", _editor._isBakeColorSpaceToGamma);

            //GUILayout.Space(5);
            //float nextPhysicsScale = EditorGUILayout.DelayedFloatField("Physic Scale", _targetPortrait._physicBakeScale);

            GUILayout.Space(5);

            //Sorting Layer
            int prevSortingLayerID = _editor._portrait._sortingLayerID;
            int prevSortingOrder   = _editor._portrait._sortingOrder;

            int layerIndex = -1;

            for (int i = 0; i < SortingLayer.layers.Length; i++)
            {
                if (SortingLayer.layers[i].id == _editor._portrait._sortingLayerID)
                {
                    //찾았다.
                    layerIndex = i;
                    break;
                }
            }
            if (layerIndex < 0)
            {
                //어라 레이어가 없는데용..
                //초기화해야겠다.
                _editor._portrait._sortingLayerID = -1;
                if (SortingLayer.layers.Length > 0)
                {
                    _editor._portrait._sortingLayerID = SortingLayer.layers[0].id;
                    layerIndex = 0;
                }
            }
            int nextIndex = EditorGUILayout.Popup("Sorting Layer", layerIndex, _sortingLayerNames);

            if (nextIndex != layerIndex)
            {
                //레이어가 변경되었다.
                if (nextIndex >= 0 && nextIndex < SortingLayer.layers.Length)
                {
                    //LayerID 변경
                    _editor._portrait._sortingLayerID = SortingLayer.layers[nextIndex].id;
                }
            }
            _editor._portrait._sortingOrder = EditorGUILayout.IntField("Sorting Order", _editor._portrait._sortingOrder);



            //CheckChangedProperties(nextRootScale, nextZScale);
            if (prevBakeScale != _targetPortrait._bakeScale ||
                prevBakeZSize != _targetPortrait._bakeZSize ||
                prevSortingLayerID != _editor._portrait._sortingLayerID ||
                prevSortingOrder != _editor._portrait._sortingOrder)
            {
                apEditorUtil.SetEditorDirty();
            }

            if (prevBakeGamma != _editor._isBakeColorSpaceToGamma

                )
            {
                apEditorUtil.SetEditorDirty();
                _editor.SaveEditorPref();
            }

            GUILayout.Space(10);


            if (GUILayout.Button(_editor.GetText(TEXT.DLG_Bake), GUILayout.Height(45)))            //"Bake"
            {
                GUI.FocusControl(null);

                //CheckChangedProperties(nextRootScale, nextZScale);
                apEditorUtil.SetEditorDirty();

                //-------------------------------------
                // Bake 함수를 실행한다. << 중요오오오오
                //-------------------------------------
                apBakeResult bakeResult = _editor.Controller.Bake();


                _editor.Notification("[" + _targetPortrait.name + "] is Baked", false, false);

                if (bakeResult.NumUnlinkedExternalObject > 0)
                {
                    EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                _editor.GetText(TEXT.Okay));
                }
            }

            GUILayout.Space(10);
            apEditorUtil.GUI_DelimeterBoxH(width - 10);
            GUILayout.Space(10);

            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_OptimizedBaking));            //"Optimized Baking"

            //"Target"
            apPortrait nextOptPortrait = (apPortrait)EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Target), _targetPortrait._bakeTargetOptPortrait, typeof(apPortrait), true);

            if (nextOptPortrait != _targetPortrait._bakeTargetOptPortrait)
            {
                //타겟을 바꾸었다.
                bool isChanged = false;
                if (nextOptPortrait != null)
                {
                    //1. 다른 Portrait를 선택했다.
                    if (!nextOptPortrait._isOptimizedPortrait)
                    {
                        //1-1. 최적화된 객체가 아니다.
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                    _editor.GetText(TEXT.OptBakeError_NotOptTarget_Body),
                                                    _editor.GetText(TEXT.Close));
                    }
                    else if (nextOptPortrait._bakeSrcEditablePortrait != _targetPortrait)
                    {
                        //1-2. 다른 대상으로부터 Bake된 Portrait같다. (물어보고 계속)
                        bool isResult = EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                                    _editor.GetText(TEXT.OptBakeError_SrcMatchError_Body),
                                                                    _editor.GetText(TEXT.Okay),
                                                                    _editor.GetText(TEXT.Cancel));

                        if (isResult)
                        {
                            //뭐 선택하겠다는데요 뭐..
                            isChanged = true;
                        }
                    }
                    else
                    {
                        //1-3. 오케이. 변경 가능
                        isChanged = true;
                    }
                }
                else
                {
                    //2. 선택을 해제했다.
                    isChanged = true;
                }

                if (isChanged)
                {
                    //Target을 변경한다.
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._bakeTargetOptPortrait = nextOptPortrait;
                }
            }

            string optBtnText = "";

            if (_targetPortrait._bakeTargetOptPortrait != null)
            {
                //optBtnText = "Optimized Bake to\n[" + _targetPortrait._bakeTargetOptPortrait.gameObject.name + "]";
                optBtnText = string.Format("{0}\n[{1}]", _editor.GetText(TEXT.DLG_OptimizedBakeTo), _targetPortrait._bakeTargetOptPortrait.gameObject.name);
            }
            else
            {
                //optBtnText = "Optimized Bake\n(Make New GameObject)";
                optBtnText = _editor.GetText(TEXT.DLG_OptimizedBakeMakeNew);
            }
            GUILayout.Space(10);

            if (GUILayout.Button(optBtnText, GUILayout.Height(45)))
            {
                GUI.FocusControl(null);

                //CheckChangedProperties(nextRootScale, nextZScale);

                //Optimized Bake를 하자
                apBakeResult bakeResult = _editor.Controller.OptimizedBake(_targetPortrait, _targetPortrait._bakeTargetOptPortrait);

                if (bakeResult.NumUnlinkedExternalObject > 0)
                {
                    EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                _editor.GetText(TEXT.Okay));
                }

                _editor.Notification("[" + _targetPortrait.name + "] is Baked (Optimized)", false, false);
            }
        }
Exemplo n.º 8
0
        // GUI
        //------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

            if (_editor == null || _targetPortrait == null)
            {
                CloseDialog();
                return;
            }

            //만약 Portriat가 바뀌었거나 Editor가 리셋되면 닫자
            if (_editor != apEditor.CurrentEditor || _targetPortrait != apEditor.CurrentEditor._portrait)
            {
                CloseDialog();
                return;
            }



            //Sorting Layer를 추가하자
            if (_sortingLayerNames == null || _sortingLayerIDs == null)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }
            else if (_sortingLayerNames.Length != SortingLayer.layers.Length ||
                     _sortingLayerIDs.Length != SortingLayer.layers.Length)
            {
                _sortingLayerNames = new string[SortingLayer.layers.Length];
                _sortingLayerIDs   = new int[SortingLayer.layers.Length];
            }

            for (int i = 0; i < SortingLayer.layers.Length; i++)
            {
                _sortingLayerNames[i] = SortingLayer.layers[i].name;
                _sortingLayerIDs[i]   = SortingLayer.layers[i].id;
            }


            int width_2Btn = (width - 14) / 2;

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Bake), _tab == TAB.Bake, width_2Btn, 25))
            {
                _tab = TAB.Bake;
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Setting), _tab == TAB.Options, width_2Btn, 25))
            {
                _tab = TAB.Options;
            }
            EditorGUILayout.EndHorizontal();


            if (_tab == TAB.Bake)
            {
                GUILayout.Space(5);

                // 1. Bake에 대한 UI
                //Bake 설정
                //EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_BakeSetting));//"Bake Setting"
                //GUILayout.Space(5);

                EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Portrait), _targetPortrait, typeof(apPortrait), true);                //"Portait"

                GUILayout.Space(5);

                //"Bake Scale"
                float prevBakeScale = _targetPortrait._bakeScale;
                _targetPortrait._bakeScale = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_BakeScale), _targetPortrait._bakeScale);

                //"Z Per Depth"
                float prevBakeZSize = _targetPortrait._bakeZSize;
                _targetPortrait._bakeZSize = EditorGUILayout.FloatField(_editor.GetText(TEXT.DLG_ZPerDepth), _targetPortrait._bakeZSize);

                if (_targetPortrait._bakeZSize < 0.5f)
                {
                    _targetPortrait._bakeZSize = 0.5f;
                }

                if (prevBakeScale != _targetPortrait._bakeScale ||
                    prevBakeZSize != _targetPortrait._bakeZSize)
                {
                    apEditorUtil.SetEditorDirty();
                }


                //Bake 버튼
                GUILayout.Space(10);
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Bake), GUILayout.Height(45)))                //"Bake"
                {
                    GUI.FocusControl(null);

                    //CheckChangedProperties(nextRootScale, nextZScale);
                    apEditorUtil.SetEditorDirty();

                    //-------------------------------------
                    // Bake 함수를 실행한다. << 중요오오오오
                    //-------------------------------------
                    apBakeResult bakeResult = _editor.Controller.Bake();


                    _editor.Notification("[" + _targetPortrait.name + "] is Baked", false, false);

                    if (bakeResult.NumUnlinkedExternalObject > 0)
                    {
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                    _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                    _editor.GetText(TEXT.Okay));
                    }
                }

                GUILayout.Space(10);
                apEditorUtil.GUI_DelimeterBoxH(width - 10);
                GUILayout.Space(10);


                //최적화 Bake
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_OptimizedBaking));                //"Optimized Baking"

                //"Target"
                apPortrait nextOptPortrait = (apPortrait)EditorGUILayout.ObjectField(_editor.GetText(TEXT.DLG_Target), _targetPortrait._bakeTargetOptPortrait, typeof(apPortrait), true);

                if (nextOptPortrait != _targetPortrait._bakeTargetOptPortrait)
                {
                    //타겟을 바꾸었다.
                    bool isChanged = false;
                    if (nextOptPortrait != null)
                    {
                        //1. 다른 Portrait를 선택했다.
                        if (!nextOptPortrait._isOptimizedPortrait)
                        {
                            //1-1. 최적화된 객체가 아니다.
                            EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                        _editor.GetText(TEXT.OptBakeError_NotOptTarget_Body),
                                                        _editor.GetText(TEXT.Close));
                        }
                        else if (nextOptPortrait._bakeSrcEditablePortrait != _targetPortrait)
                        {
                            //1-2. 다른 대상으로부터 Bake된 Portrait같다. (물어보고 계속)
                            bool isResult = EditorUtility.DisplayDialog(_editor.GetText(TEXT.OptBakeError_Title),
                                                                        _editor.GetText(TEXT.OptBakeError_SrcMatchError_Body),
                                                                        _editor.GetText(TEXT.Okay),
                                                                        _editor.GetText(TEXT.Cancel));

                            if (isResult)
                            {
                                //뭐 선택하겠다는데요 뭐..
                                isChanged = true;
                            }
                        }
                        else
                        {
                            //1-3. 오케이. 변경 가능
                            isChanged = true;
                        }
                    }
                    else
                    {
                        //2. 선택을 해제했다.
                        isChanged = true;
                    }

                    if (isChanged)
                    {
                        //Target을 변경한다.
                        apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                        _targetPortrait._bakeTargetOptPortrait = nextOptPortrait;
                    }
                }

                string optBtnText = "";
                if (_targetPortrait._bakeTargetOptPortrait != null)
                {
                    //optBtnText = "Optimized Bake to\n[" + _targetPortrait._bakeTargetOptPortrait.gameObject.name + "]";
                    optBtnText = string.Format("{0}\n[{1}]", _editor.GetText(TEXT.DLG_OptimizedBakeTo), _targetPortrait._bakeTargetOptPortrait.gameObject.name);
                }
                else
                {
                    //optBtnText = "Optimized Bake\n(Make New GameObject)";
                    optBtnText = _editor.GetText(TEXT.DLG_OptimizedBakeMakeNew);
                }
                GUILayout.Space(10);

                if (GUILayout.Button(optBtnText, GUILayout.Height(45)))
                {
                    GUI.FocusControl(null);

                    //CheckChangedProperties(nextRootScale, nextZScale);

                    //Optimized Bake를 하자
                    apBakeResult bakeResult = _editor.Controller.OptimizedBake(_targetPortrait, _targetPortrait._bakeTargetOptPortrait);

                    if (bakeResult.NumUnlinkedExternalObject > 0)
                    {
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.BakeWarning_Title),
                                                    _editor.GetTextFormat(TEXT.BakeWarning_Body, bakeResult.NumUnlinkedExternalObject),
                                                    _editor.GetText(TEXT.Okay));
                    }

                    _editor.Notification("[" + _targetPortrait.name + "] is Baked (Optimized)", false, false);
                }
            }
            else
            {
                //Vector2 curScroll = (_tab == TAB.Bake) ? _scroll_Bake : _scroll_Options;

                _scroll_Options = EditorGUILayout.BeginScrollView(_scroll_Options, false, true, GUILayout.Width(width), GUILayout.Height(height - 30));

                EditorGUILayout.BeginVertical(GUILayout.Width(width - 24));
                GUILayout.Space(5);

                width -= 24;

                // 2. Option에 대한 UI
                //1. Gamma Space Space
                bool prevBakeGamma   = _editor._isBakeColorSpaceToGamma;
                int  iPrevColorSpace = prevBakeGamma ? 0 : 1;
                int  iNextColorSpace = EditorGUILayout.Popup(_editor.GetUIWord(UIWORD.ColorSpace), iPrevColorSpace, _colorSpaceNames);
                if (iNextColorSpace != iPrevColorSpace)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (iNextColorSpace == 0)
                    {
                        //Gamma
                        _editor._isBakeColorSpaceToGamma = true;
                    }
                    else
                    {
                        //Linear
                        _editor._isBakeColorSpaceToGamma = false;
                    }
                }

                GUILayout.Space(10);

                //2. Sorting Layer
                int prevSortingLayerID = _editor._portrait._sortingLayerID;
                int prevSortingOrder   = _editor._portrait._sortingOrder;

                int layerIndex = -1;
                for (int i = 0; i < SortingLayer.layers.Length; i++)
                {
                    if (SortingLayer.layers[i].id == _editor._portrait._sortingLayerID)
                    {
                        //찾았다.
                        layerIndex = i;
                        break;
                    }
                }
                if (layerIndex < 0)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);

                    //어라 레이어가 없는데용..
                    //초기화해야겠다.
                    _editor._portrait._sortingLayerID = -1;
                    if (SortingLayer.layers.Length > 0)
                    {
                        _editor._portrait._sortingLayerID = SortingLayer.layers[0].id;
                        layerIndex = 0;
                    }
                }
                int nextIndex = EditorGUILayout.Popup(_editor.GetText(TEXT.SortingLayer), layerIndex, _sortingLayerNames);                //"Sorting Layer"
                if (nextIndex != layerIndex)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    //레이어가 변경되었다.
                    if (nextIndex >= 0 && nextIndex < SortingLayer.layers.Length)
                    {
                        //LayerID 변경
                        _editor._portrait._sortingLayerID = SortingLayer.layers[nextIndex].id;
                    }
                }
                _editor._portrait._sortingOrder = EditorGUILayout.IntField(_editor.GetText(TEXT.SortingOrder), _editor._portrait._sortingOrder);                //"Sorting Order"

                GUILayout.Space(10);

                //3. 메카님 사용 여부

                //EditorGUILayout.LabelField("Animation Settings");
                bool   prevIsUsingMecanim = _targetPortrait._isUsingMecanim;
                string prevMecanimPath    = _targetPortrait._mecanimAnimClipResourcePath;
                _targetPortrait._isUsingMecanim = EditorGUILayout.Toggle(_editor.GetText(TEXT.IsMecanimAnimation), _targetPortrait._isUsingMecanim); //"Is Mecanim Animation"
                EditorGUILayout.LabelField(_editor.GetText(TEXT.AnimationClipExportPath));                                                           //"Animation Clip Export Path"

                GUIStyle guiStyle_ChangeBtn = new GUIStyle(GUI.skin.button);
                guiStyle_ChangeBtn.margin = GUI.skin.textField.margin;
                guiStyle_ChangeBtn.border = GUI.skin.textField.border;

                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(20));
                GUILayout.Space(5);
                EditorGUILayout.TextField(_targetPortrait._mecanimAnimClipResourcePath, GUILayout.Width(width - (70 + 15)));
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Change), guiStyle_ChangeBtn, GUILayout.Width(70), GUILayout.Height(18)))
                {
                    string defaultPath = _targetPortrait._mecanimAnimClipResourcePath;
                    if (string.IsNullOrEmpty(defaultPath))
                    {
                        defaultPath = Application.dataPath;
                    }
                    string nextPath = EditorUtility.SaveFolderPanel("Select to export animation clips", defaultPath, "");
                    if (!string.IsNullOrEmpty(nextPath))
                    {
                        if (apEditorUtil.IsInAssetsFolder(nextPath))
                        {
                            //유효한 폴더인 경우
                            _targetPortrait._mecanimAnimClipResourcePath = nextPath;
                        }
                        else
                        {
                            //유효한 폴더가 아닌 경우
                            EditorUtility.DisplayDialog("Invalid Folder Path", "Invalid Clip Path", "Close");
                        }
                    }

                    GUI.FocusControl(null);
                }
                EditorGUILayout.EndHorizontal();



                GUILayout.Space(10);

                //4. Important
                //"Is Important"
                bool nextImportant = EditorGUILayout.Toggle(new GUIContent(_editor.GetText(TEXT.DLG_Setting_IsImportant), "When this setting is on, it always updates and the physics effect works."), _targetPortrait._isImportant);
                if (nextImportant != _targetPortrait._isImportant)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._isImportant = nextImportant;
                }

                //"FPS (Important Off)"
                int nextFPS = EditorGUILayout.DelayedIntField(new GUIContent(_editor.GetText(TEXT.DLG_Setting_FPS), "This setting is used when <Important> is off"), _targetPortrait._FPS);
                if (_targetPortrait._FPS != nextFPS)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (nextFPS < 10)
                    {
                        nextFPS = 10;
                    }
                    _targetPortrait._FPS = nextFPS;
                }

                GUILayout.Space(10);

                //5. Billboard + Perspective

                apPortrait.BILLBOARD_TYPE nextBillboardType = (apPortrait.BILLBOARD_TYPE)EditorGUILayout.Popup(_editor.GetText(TEXT.DLG_Billboard), (int)_targetPortrait._billboardType, _billboardTypeNames);
                if (nextBillboardType != _targetPortrait._billboardType)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._billboardType = nextBillboardType;
                }

                GUILayout.Space(10);

                //6. Shadow

                apPortrait.SHADOW_CASTING_MODE nextChastShadows = (apPortrait.SHADOW_CASTING_MODE)EditorGUILayout.EnumPopup(_editor.GetUIWord(UIWORD.CastShadows), _targetPortrait._meshShadowCastingMode);
                bool nextReceiveShaodw = EditorGUILayout.Toggle(_editor.GetUIWord(UIWORD.ReceiveShadows), _targetPortrait._meshReceiveShadow);
                if (nextChastShadows != _targetPortrait._meshShadowCastingMode ||
                    nextReceiveShaodw != _targetPortrait._meshReceiveShadow)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    _targetPortrait._meshShadowCastingMode = nextChastShadows;
                    _targetPortrait._meshReceiveShadow     = nextReceiveShaodw;
                }

                GUILayout.Space(10);

#if UNITY_2018_2_OR_NEWER
                //7. LWRP
                //LWRP 쉐이더를 쓸지 여부와 다시 강제로 생성하기 버튼을 만들자.
                bool prevUseLWRP  = _editor._isUseLWRPShader;
                int  iPrevUseLWRP = prevUseLWRP ? 1 : 0;
                int  iNextUseLWRP = EditorGUILayout.Popup("Render Pipeline", iPrevUseLWRP, _renderPipelineNames);
                if (iNextUseLWRP != iPrevUseLWRP)
                {
                    apEditorUtil.SetRecord_Portrait(apUndoGroupData.ACTION.Portrait_SettingChanged, _editor, _targetPortrait, null, false);
                    if (iNextUseLWRP == 0)
                    {
                        //사용 안함
                        _editor._isUseLWRPShader = false;
                    }
                    else
                    {
                        //LWRP 사용함
                        _editor._isUseLWRPShader = true;
                    }
                }
                if (GUILayout.Button("Generate Lightweight Shaders"))
                {
                    apShaderGenerator shaderGenerator = new apShaderGenerator();
                    shaderGenerator.GenerateLWRPShaders();
                }

                GUILayout.Space(10);
#endif

                //11.7 추가 : Ambient Light를 검은색으로 만든다.
                GUILayout.Space(10);
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_AmbientToBlack), GUILayout.Height(20)))
                {
                    MakeAmbientLightToBlack();
                }

                //CheckChangedProperties(nextRootScale, nextZScale);
                if (prevSortingLayerID != _editor._portrait._sortingLayerID ||
                    prevSortingOrder != _editor._portrait._sortingOrder ||
                    prevIsUsingMecanim != _targetPortrait._isUsingMecanim ||
                    !string.Equals(prevMecanimPath, _targetPortrait._mecanimAnimClipResourcePath) ||
                    prevBakeGamma != _editor._isBakeColorSpaceToGamma
#if UNITY_2018_2_OR_NEWER
                    || prevUseLWRP != _editor._isUseLWRPShader
#endif
                    )
                {
                    apEditorUtil.SetEditorDirty();
                    _editor.SaveEditorPref();
                }

                GUILayout.Space(height + 500);
                EditorGUILayout.EndVertical();

                EditorGUILayout.EndScrollView();
            }

            GUILayout.Space(5);
        }