示例#1
0
        // GUI
        //------------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

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

            Texture2D iconImageCategory = _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_FoldDown);

            int   height_List = height - 480;
            Color prevColor   = GUI.backgroundColor;

            GUI.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
            GUI.Box(new Rect(0, 156, width, height_List), "");
            GUI.backgroundColor = prevColor;

            EditorGUILayout.BeginVertical();

            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_SelectedPhysicsSetting));            //"Selected Physics Setting"

            //현재 선택한 Physics Param을 등록하는 UI

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

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

            GUILayout.Box(_targetModMesh._renderUnit.Name, boxGUIStyle, GUILayout.Width(width - 8), GUILayout.Height(20));

            GUILayout.Space(5);
            int width_Left  = 90;
            int width_Right = width - 110;

            //Icon 이미지		|	이름	Icon 타입
            //					|	(저장)
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(70));
            GUILayout.Space(5);
            EditorGUILayout.BeginVertical(GUILayout.Width(width_Left), GUILayout.Height(70));
            //Icon을 출력하자
            Texture2D addParamIcon = _editor.ImageSet.Get(apEditorUtil.GetPhysicsPresetIconType(_addParamIcon));

            GUILayout.Box(addParamIcon, boxGUIStyle, GUILayout.Width(65), GUILayout.Height(65));
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical(GUILayout.Width(width_Right), GUILayout.Height(70));
            //이름, Icon 및 등록 버튼

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Name), GUILayout.Width(80));            //"Name"
            _strAddParamName = EditorGUILayout.TextField(_strAddParamName, GUILayout.Width(width_Right - 88));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Icon), GUILayout.Width(80));            //"Icon"
            _addParamIcon = (apPhysicsPresetUnit.ICON)EditorGUILayout.EnumPopup(_addParamIcon, GUILayout.Width(width_Right - 88));
            EditorGUILayout.EndHorizontal();
            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            if (GUILayout.Button(_editor.GetText(TEXT.DLG_RegistToPreset), GUILayout.Width(150)))            //"Regist To Preset"
            {
                //TODO
                if (_targetModMesh.PhysicParam != null)
                {
                    //bool result = EditorUtility.DisplayDialog("Regist to Preset", "Regist Preset [" + _strAddParamName + "] ?", "Regist", "Cancel");
                    bool result = EditorUtility.DisplayDialog(_editor.GetText(TEXT.PhysicPreset_Regist_Title),
                                                              _editor.GetTextFormat(TEXT.PhysicPreset_Regist_Body, _strAddParamName),
                                                              _editor.GetText(TEXT.PhysicPreset_Regist_Okay),
                                                              _editor.GetText(TEXT.Cancel));

                    if (result)
                    {
                        _editor.PhysicsPreset.AddNewPreset(_targetModMesh.PhysicParam, _strAddParamName, _addParamIcon);
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(5);
            apEditorUtil.GUI_DelimeterBoxH(width);
            GUILayout.Space(5);


            GUIStyle guiStyle = new GUIStyle(GUIStyle.none);

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

            GUIStyle guiStyle_NotSelectable = new GUIStyle(GUIStyle.none);

            guiStyle_NotSelectable.normal.textColor = Color.red;
            guiStyle_NotSelectable.alignment        = TextAnchor.MiddleLeft;


            GUIStyle guiStyle_Center = new GUIStyle(GUIStyle.none);

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

            //GUIContent guiContent_Bone = new GUIContent(iconBone);

            GUILayout.Space(10);
            //GUILayout.Button("Select a Physics Preset", guiStyle_Center, GUILayout.Width(width), GUILayout.Height(15));//<투명 버튼


            _scrollList = EditorGUILayout.BeginScrollView(_scrollList, GUILayout.Width(width), GUILayout.Height(height_List));

            //"Presets"
            GUILayout.Button(new GUIContent(_editor.GetText(TEXT.DLG_Presets), iconImageCategory), guiStyle, GUILayout.Height(20));            //<투명 버튼

            for (int i = 0; i < _editor.PhysicsPreset.Presets.Count; i++)
            {
                //DrawBoneUnit(_boneUnits_Root[i], 0, width, iconImage_FoldDown, iconImage_FoldRight, guiContent_Bone, guiStyle, guiStyle_NotSelectable, _scrollList.x);
                DrawPresetUnit(_editor.PhysicsPreset.Presets[i], i, width - 18, _scrollList.x);
            }

            GUILayout.Space(310);

            EditorGUILayout.EndScrollView();

            EditorGUILayout.EndVertical();

            GUILayout.Space(10);



            //선택한 정보를 보여주자
            //string curName = "<Not Selected>";
            string    curName = "<" + _editor.GetText(TEXT.DLG_NotSelected) + ">";
            Texture2D curIcon = null;

            float curMoveRange = 0.0f;
            //float curStretchRange_Min = 0.0f;
            float curStretchRange_Max       = 0.0f;
            float curStretchK               = 0.0f;
            float curInertiaK               = 0.0f;
            float curDamping                = 0.0f;
            float curMass                   = 100.0f;
            bool  curIsRestrictMoveRange    = false;
            bool  curIsRestrictStretchRange = false;


            Vector2 curGravityConstValue = Vector2.zero;
            Vector2 curWindConstValue    = Vector2.zero;
            Vector2 curWindRandomRange   = Vector2.zero;

            float curAirDrag   = 0.0f;
            float curViscosity = 0.0f;
            float curRestoring = 1.0f;

            if (_selectedUnit != null)
            {
                curName = _selectedUnit._name;
                curIcon = _editor.ImageSet.Get(apEditorUtil.GetPhysicsPresetIconType(_selectedUnit._icon));
                //curStretchRange_Min = _selectedUnit._stretchRange_Min;
                curStretchRange_Max = _selectedUnit._stretchRange_Max;

                curIsRestrictMoveRange    = _selectedUnit._isRestrictMoveRange;
                curIsRestrictStretchRange = _selectedUnit._isRestrictStretchRange;

                curMoveRange = _selectedUnit._moveRange;
                curStretchK  = _selectedUnit._stretchK;
                curInertiaK  = _selectedUnit._inertiaK;
                curDamping   = _selectedUnit._damping;
                curMass      = _selectedUnit._mass;


                curGravityConstValue = _selectedUnit._gravityConstValue;
                curWindConstValue    = _selectedUnit._windConstValue;
                curWindRandomRange   = _selectedUnit._windRandomRange;

                curAirDrag   = _selectedUnit._airDrag;
                curViscosity = _selectedUnit._viscosity;
                curRestoring = _selectedUnit._restoring;
            }

            Texture2D imgIcon_Stretch   = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Stretch);
            Texture2D imgIcon_Inertia   = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Inertia);
            Texture2D imgIcon_Restoring = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Recover);
            Texture2D imgIcon_Viscosity = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Viscosity);
            Texture2D imgIcon_Gravity   = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Gravity);
            Texture2D imgIcon_Wind      = _editor.ImageSet.Get(apImageSet.PRESET.Physic_Wind);
            //반반 나눠서 그려주자
            int width_Info      = ((width - 10) / 2) - 10;
            int height_Info     = 270;
            int width_InfoLabel = 120;
            int width_InfoValue = (width_Info - width_InfoLabel) - 4;

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(height_Info));
            GUILayout.Space(5);
            EditorGUILayout.BeginVertical(GUILayout.Width(width_Info), GUILayout.Height(height_Info));
            //Icon, Name, Basic Setting, Gravity, Wind를 보여주자
            if (curIcon == null)
            {
                EditorGUILayout.LabelField(curName, GUILayout.Width(width_Info), GUILayout.Height(26));
            }
            else
            {
                EditorGUILayout.LabelField(new GUIContent("  " + curName, curIcon), GUILayout.Width(width_Info), GUILayout.Height(26));
            }
            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.Mass), GUILayout.Width(width_InfoLabel));            //"Mass"
            EditorGUILayout.FloatField(curMass, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.Damping), GUILayout.Width(width_InfoLabel));            //"Damping"
            EditorGUILayout.FloatField(curDamping, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.AirDrag), GUILayout.Width(width_InfoLabel));            //"Air Drag"
            EditorGUILayout.FloatField(curAirDrag, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();


            if (curIsRestrictMoveRange)
            {
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.MoveRange), GUILayout.Width(width_InfoLabel));                //"Move Range"
                EditorGUILayout.FloatField(curMoveRange, GUILayout.Width(width_InfoValue));
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.MoveRangeUnlimited), GUILayout.Width(width_Info));                //"Move Range : (Unlimited)"
                EditorGUILayout.EndHorizontal();
            }



            GUILayout.Space(5);

            //"  Gravity"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Gravity), imgIcon_Gravity), GUILayout.Width(width_Info), GUILayout.Height(25));
            apEditorUtil.DelayedVector2Field(curGravityConstValue, width_Info - 4);

            GUILayout.Space(5);
            //"  Wind"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Wind), imgIcon_Wind), GUILayout.Width(width_Info), GUILayout.Height(25));
            apEditorUtil.DelayedVector2Field(curWindConstValue, width_Info - 4);
            EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.WindRandomRangeSize), GUILayout.Width(width_Info));            //"Wind Random Size"
            apEditorUtil.DelayedVector2Field(curWindRandomRange, width_Info - 4);

            EditorGUILayout.EndVertical();

            GUILayout.Space(4);

            EditorGUILayout.BeginVertical(GUILayout.Width(width_Info), GUILayout.Height(height_Info));
            //Stretchiness, Inertia, Restoring, Viscosity를 보여주고, 삭제 버튼(또는 Reserved) 표시

            //"  Stretchiness"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Stretchiness), imgIcon_Stretch), GUILayout.Width(width_Info), GUILayout.Height(25));
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.K_Value), GUILayout.Width(width_InfoLabel));            //"K-Value"
            EditorGUILayout.FloatField(curStretchK, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            if (curIsRestrictStretchRange)
            {
                //EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                //EditorGUILayout.LabelField("Shorten Range", GUILayout.Width(width_InfoLabel));
                //EditorGUILayout.FloatField(curStretchRange_Min, GUILayout.Width(width_InfoValue));
                //EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.LengthenRatio), GUILayout.Width(width_InfoLabel));                //"Lengthen Range"
                EditorGUILayout.FloatField(curStretchRange_Max, GUILayout.Width(width_InfoValue));
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                //EditorGUILayout.LabelField("Shorten Range : (Unlimited)", GUILayout.Width(width_Info));
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                EditorGUILayout.LabelField(_editor.GetUIWord(UIWORD.LengthenRatioUnlimited), GUILayout.Width(width_Info));                //"Lengthen Range : (Unlimited)"
                EditorGUILayout.EndHorizontal();
            }


            GUILayout.Space(5);

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            //"  Inertia"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Inertia), imgIcon_Inertia), GUILayout.Width(width_InfoLabel), GUILayout.Height(25));
            EditorGUILayout.FloatField(curInertiaK, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            //"  Restoring"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Restoring), imgIcon_Restoring), GUILayout.Width(width_InfoLabel), GUILayout.Height(25));
            EditorGUILayout.FloatField(curRestoring, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
            //"  Viscosity"
            EditorGUILayout.LabelField(new GUIContent("  " + _editor.GetUIWord(UIWORD.Viscosity), imgIcon_Viscosity), GUILayout.Width(width_InfoLabel), GUILayout.Height(25));
            EditorGUILayout.FloatField(curViscosity, GUILayout.Width(width_InfoValue));
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);
            if (_selectedUnit != null)
            {
                //삭제 가능한지 체크
                if (!_selectedUnit._isReserved)
                {
                    //"Remove Preset"
                    if (GUILayout.Button(_editor.GetText(TEXT.DLG_RemovePreset), GUILayout.Width(width_Info - 4)))
                    {
                        //bool result = EditorUtility.DisplayDialog("Remove Preset", "Remove Preset [" + _selectedUnit._name + "] ?", "Remove", "Cancel");
                        bool result = EditorUtility.DisplayDialog(_editor.GetText(TEXT.PhysicPreset_Remove_Title),
                                                                  _editor.GetTextFormat(TEXT.PhysicPreset_Remove_Body, _selectedUnit._name),
                                                                  _editor.GetText(TEXT.Remove),
                                                                  _editor.GetText(TEXT.Cancel));

                        if (result)
                        {
                            int targetID = _selectedUnit._uniqueID;
                            _selectedUnit = null;

                            _editor.PhysicsPreset.RemovePreset(targetID);
                        }
                    }
                }
            }

            EditorGUILayout.EndVertical();

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            bool isClose = false;
            bool isSelectBtnAvailable = _selectedUnit != null;

            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Apply), false, isSelectBtnAvailable, (width / 2) - 8, 30))            //"Apply"
            {
                _funcResult(true, _loadKey, _selectedUnit, _targetModMesh);
                isClose = true;
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Close), false, true, (width / 2) - 8, 30))            //"Close"
            {
                //_funcResult(false, _loadKey, null, null);
                _funcResult(false, _loadKey, null, _targetModMesh);
                isClose = true;
            }
            EditorGUILayout.EndHorizontal();

            if (isClose)
            {
                CloseDialog();
            }
        }
        // GUI
        //------------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

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

            Color prevColor = GUI.backgroundColor;

            //레이아웃 구조
            //1. Save
            // - 저장 버튼
            //2. Load
            // - 로드 버튼
            // - 본 정보 리스트
            //   - <색상> 인덱스, 이름 -> 적용 여부 + IK + 색상 로드
            // - 전체 선택 / 해제
            // - 전체 IK 포함 여부,
            // - 옵션 : 크기

            width -= 10;

            //1. Save
            GUIStyle guiStyleBox = new GUIStyle(GUI.skin.box);

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

            GUIStyle guiStyleBox_Left = new GUIStyle(GUI.skin.textField);

            guiStyleBox_Left.alignment = TextAnchor.MiddleLeft;

            //"  Export Bone Structure"
            GUILayout.Box(new GUIContent("  " + _editor.GetText(TEXT.DLG_ExportBoneStructure), _editor.ImageSet.Get(apImageSet.PRESET.Rig_SaveLoad)), guiStyleBox, GUILayout.Width(width), GUILayout.Height(35));
            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            int nBones = _targetMeshGroup._boneList_All.Count;
            //int nBones = _targetMeshGroup._boneList_All
            string strBones = "";

            if (nBones == 0)
            {
                //strBones = "No Bones to Export";
                strBones = _editor.GetText(TEXT.DLG_NoBonesToExport);
            }
            else if (nBones == 1)
            {
                //strBones = "1 Bone to Export";
                strBones = _editor.GetText(TEXT.DLG_1BoneToExport);
            }
            else
            {
                //strBones = nBones + " Bones to Export";
                strBones = _editor.GetTextFormat(TEXT.DLG_NBonesToExport, nBones);
            }
            if (nBones > 0)
            {
                GUI.backgroundColor = new Color(prevColor.r * 0.8f, prevColor.g * 1.5f, prevColor.b * 1.5f, 1.0f);
            }
            else
            {
                GUI.backgroundColor = new Color(prevColor.r * 1.5f, prevColor.g * 0.8f, prevColor.b * 0.8f, 1.0f);
            }
            GUILayout.Box(strBones, guiStyleBox, GUILayout.Width(width - 120), GUILayout.Height(25));
            GUI.backgroundColor = prevColor;

            //" Export"
            if (apEditorUtil.ToggledButton(_editor.ImageSet.Get(apImageSet.PRESET.Rig_SaveLoad), " " + _editor.GetText(TEXT.Export), false, (nBones > 0), 115, 25))
            {
                string saveFilePath = EditorUtility.SaveFilePanel("Save Bone Structure", "", "", "apb");
                if (!string.IsNullOrEmpty(saveFilePath))
                {
                    //Save를 하자
                    bool isResult = apRetarget.SaveBaseStruct(_targetMeshGroup, saveFilePath);
                    if (isResult)
                    {
                        _editor.Notification("[" + saveFilePath + "] is Saved", false, false);
                        //Debug.Log("[" + saveFilePath + "] is Saved");
                    }
                    else
                    {
                        //Debug.LogError("File Save Failed");
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

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


            //2. Load
            // - 로드 버튼
            // - 본 정보 리스트
            //   - <색상> 인덱스, 이름 -> 적용 여부 + IK + 색상 로드
            // - 전체 선택 / 해제
            // - 전체 IK 포함 여부,
            // - 옵션 : 크기
            //"  Import Bone Structure"
            GUILayout.Box(new GUIContent("  " + _editor.GetText(TEXT.DLG_ImportBoneStructure), _editor.ImageSet.Get(apImageSet.PRESET.Rig_LoadBones)), guiStyleBox, GUILayout.Width(width), GUILayout.Height(35));
            GUILayout.Space(5);

            //로드한 파일 정보
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            //TODO :
            bool   isFileLoaded = _retargetData.IsBaseFileLoaded;
            string strFileName  = _retargetData.BaseLoadedFilePath;

            if (isFileLoaded)
            {
                GUI.backgroundColor = new Color(prevColor.r * 0.8f, prevColor.g * 2.0f, prevColor.b * 0.8f, 1.0f);
            }
            else
            {
                //strFileName = "No File is Imported";
                strFileName         = _editor.GetText(TEXT.DLG_NoFileIsImported);
                GUI.backgroundColor = new Color(prevColor.r * 1.5f, prevColor.g * 0.8f, prevColor.b * 0.8f, 1.0f);
            }

            EditorGUILayout.TextField(strFileName, guiStyleBox_Left, GUILayout.Width(width - 120), GUILayout.Height(25));
            GUI.backgroundColor = prevColor;

            //"Load File"
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_LoadFile), false, true, 115, 25))
            {
                string loadFilePath = EditorUtility.OpenFilePanel("Open Bone Structure", "", "apb");
                if (!string.IsNullOrEmpty(loadFilePath))
                {
                    bool loadResult = _retargetData.LoadBaseStruct(loadFilePath);
                    if (loadResult)
                    {
                        _editor.Notification("[" + loadFilePath + "] is Loaded", false, false);
                        //Debug.Log("[" + loadFilePath + "] is Loaded");
                    }
                }
            }

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(5);
            int listHeight = height - 450;

            Rect lastRect = GUILayoutUtility.GetLastRect();

            GUI.backgroundColor = new Color(0.7f, 0.7f, 0.7f);
            GUI.Box(new Rect(0, lastRect.y + 5, width + 10, listHeight), "");
            GUI.backgroundColor = prevColor;


            List <apRetargetBoneUnit> baseBoneUnits = _retargetData.BaseBoneUnits;

            _scrollList = EditorGUILayout.BeginScrollView(_scrollList, false, true, GUILayout.Width(width + 10), GUILayout.Height(listHeight));
            EditorGUILayout.BeginVertical(GUILayout.Width(width - 20));

            if (baseBoneUnits != null)
            {
                GUIStyle guiStyle_ItemLabel = new GUIStyle(GUI.skin.label);
                guiStyle_ItemLabel.alignment = TextAnchor.MiddleLeft;

                GUIStyle guiStyle_ItemTextBox = new GUIStyle(GUI.skin.textField);
                guiStyle_ItemTextBox.alignment = TextAnchor.MiddleLeft;

                //   - <색상> 인덱스, 이름 -> 적용 여부 + IK + 색상 로드
                apRetargetBoneUnit boneUnit = null;
                int itemWidth  = width - 20;
                int itemHeight = 20;

                string strImport   = _editor.GetText(TEXT.DLG_Import);
                string strNoImport = _editor.GetText(TEXT.DLG_NoImport);
                string strIK       = "IK";          //<<이건 고유명사
                string strNoIK     = _editor.GetText(TEXT.DLG_NoIK);
                string strShape    = _editor.GetText(TEXT.DLG_Shape);
                string strNoShape  = _editor.GetText(TEXT.DLG_NoShape);

                for (int i = 0; i < baseBoneUnits.Count; i++)
                {
                    boneUnit = baseBoneUnits[i];
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(itemWidth), GUILayout.Height(itemHeight));
                    GUILayout.Space(10);
                    GUI.backgroundColor = boneUnit._color;
                    GUILayout.Box("", apEditorUtil.WhiteGUIStyle_Box, GUILayout.Width(16), GUILayout.Height(16));
                    GUI.backgroundColor = prevColor;

                    EditorGUILayout.LabelField(boneUnit._unitID.ToString(), guiStyle_ItemLabel, GUILayout.Width(30), GUILayout.Height(itemHeight));
                    boneUnit._name = EditorGUILayout.TextField(boneUnit._name, guiStyle_ItemTextBox, GUILayout.Width(120), GUILayout.Height(itemHeight));

                    GUILayout.Space(20);

                    //"Import", "Not Import"
                    if (apEditorUtil.ToggledButton_2Side(strImport, strNoImport, boneUnit._isImportEnabled, true, 100, itemHeight))
                    {
                        boneUnit._isImportEnabled = !boneUnit._isImportEnabled;
                    }
                    GUILayout.Space(10);
                    //"IK", "No IK"
                    if (apEditorUtil.ToggledButton_2Side(strIK, strNoIK, boneUnit._isIKEnabled, boneUnit._isImportEnabled, 70, itemHeight))
                    {
                        boneUnit._isIKEnabled = !boneUnit._isIKEnabled;
                    }
                    //"Shape", "No Shape"
                    if (apEditorUtil.ToggledButton_2Side(strShape, strNoShape, boneUnit._isShapeEnabled, boneUnit._isImportEnabled, 70, itemHeight))
                    {
                        boneUnit._isShapeEnabled = !boneUnit._isShapeEnabled;
                    }

                    EditorGUILayout.EndHorizontal();
                }
            }

            EditorGUILayout.EndVertical();
            GUILayout.Space(listHeight + 100);
            EditorGUILayout.EndScrollView();
            GUILayout.Space(20);

            // - 전체 선택 / 해제
            // - 전체 IK 포함 여부,
            // - 옵션 : 크기
            int widthHalf = (width / 2) - 4;

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_EnableAllBones), false, isFileLoaded, widthHalf, 25))            //"Enable All Bones"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isImportEnabled = true;
                    }
                }
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_DisableAllBones), false, isFileLoaded, widthHalf, 25))            //"Disable All Bones"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isImportEnabled = false;
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_EnableAllIK), false, isFileLoaded, widthHalf, 25))            //"Enable All IK"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isIKEnabled = true;
                    }
                }
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_DisableAllIK), false, isFileLoaded, widthHalf, 25))            //"Disable All IK"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isIKEnabled = false;
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(25));
            GUILayout.Space(5);
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_EnableAllShape), false, isFileLoaded, widthHalf, 25))            //"Enable All Shape"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isShapeEnabled = true;
                    }
                }
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_DisableAllShape), false, isFileLoaded, widthHalf, 25))            //"Disable All Shape"
            {
                if (baseBoneUnits != null)
                {
                    for (int i = 0; i < baseBoneUnits.Count; i++)
                    {
                        baseBoneUnits[i]._isShapeEnabled = false;
                    }
                }
            }
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);

            int widthLabel = 150;
            int widthValue = width - 155;

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(20));
            GUILayout.Space(5);

            //"Import Scale"
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_ImportScale), GUILayout.Width(widthLabel));
            _retargetData._importScale = EditorGUILayout.FloatField(_retargetData._importScale, GUILayout.Width(widthValue));
            EditorGUILayout.EndHorizontal();

            GUILayout.Space(10);
            bool isClose = false;
            bool isSelectBtnAvailable = _retargetData.IsBaseFileLoaded;            //<<TODO : 파일을 연게 있다면 이게 true

            //"  Import to [" + _targetMeshGroup._name + "]"
            if (apEditorUtil.ToggledButton(_editor.ImageSet.Get(apImageSet.PRESET.Rig_LoadBones),
                                           "  " + _editor.GetTextFormat(TEXT.DLG_ImportToMeshGroup, _targetMeshGroup._name), false, isSelectBtnAvailable, width, 30))
            {
                _funcResult(true, _loadKey, _retargetData, _targetMeshGroup);
                isClose = true;
            }

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

            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Close), false, true, width, 30))            //"Close"
            {
                //_funcResult(false, _loadKey, null, null);
                _funcResult(false, _loadKey, null, _targetMeshGroup);
                isClose = true;
            }

            if (isClose)
            {
                CloseDialog();
            }
        }
        // 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);
            }
        }
        // GUI
        //------------------------------------------------------------------------
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

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

            int   height_List = height - 450;
            Color prevColor   = GUI.backgroundColor;

            GUI.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
            GUI.Box(new Rect(0, 156, width, height_List), "");
            GUI.backgroundColor = prevColor;

            EditorGUILayout.BeginVertical();

            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_SelectedControlParamSetting));            //"Selected Controller Parameter Setting"

            //현재 선택한 Physics Param을 등록하는 UI

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

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

            GUILayout.Box(_targetControlParam._keyName, boxGUIStyle, GUILayout.Width(width - 8), GUILayout.Height(20));

            GUILayout.Space(5);
            int width_Left  = 90;
            int width_Right = width - 110;

            //Icon 이미지 | 이름, ValueType과 값 범위 (수정 불가)
            //            | 저장 버튼

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(70));
            GUILayout.Space(5);
            EditorGUILayout.BeginVertical(GUILayout.Width(width_Left), GUILayout.Height(70));
            //Icon을 출력하자
            Texture2D addParamIcon = _editor.ImageSet.Get(apEditorUtil.GetControlParamPresetIconType(_targetControlParam._iconPreset));

            GUILayout.Box(addParamIcon, boxGUIStyle, GUILayout.Width(65), GUILayout.Height(65));
            EditorGUILayout.EndVertical();

            EditorGUILayout.BeginVertical(GUILayout.Width(width_Right), GUILayout.Height(70));
            //이름, Icon 및 등록 버튼

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Range), GUILayout.Width(80));            //"Range"
            EditorGUILayout.LabelField(_strValueInfo, GUILayout.Width(width_Right - 88));
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Default), GUILayout.Width(80));            //"Default"
            EditorGUILayout.LabelField(_strDefaultInfo, GUILayout.Width(width_Right - 88));
            EditorGUILayout.EndHorizontal();
            GUILayout.Space(5);
            EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Right));
            if (GUILayout.Button(_editor.GetText(TEXT.DLG_RegistToPreset), GUILayout.Width(150)))            //"Regist To Preset"
            {
                //bool result = EditorUtility.DisplayDialog("Regist to Preset", "Regist Preset [" + _strAddParamName + "] ?", "Regist", "Cancel");
                bool result = EditorUtility.DisplayDialog(_editor.GetText(TEXT.ControlParamPreset_Regist_Title),
                                                          _editor.GetTextFormat(TEXT.ControlParamPreset_Regist_Body, _strAddParamName),
                                                          _editor.GetText(TEXT.ControlParamPreset_Regist_Okay),
                                                          _editor.GetText(TEXT.Cancel));

                if (result)
                {
                    //Control Param으로 추가하자
                    _editor.ControlParamPreset.AddNewPreset(_targetControlParam);
                }
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.EndVertical();

            EditorGUILayout.EndHorizontal();

            GUILayout.Space(5);
            apEditorUtil.GUI_DelimeterBoxH(width);
            GUILayout.Space(5);


            GUIStyle guiStyle = new GUIStyle(GUIStyle.none);

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

            GUIStyle guiStyle_NotSelectable = new GUIStyle(GUIStyle.none);

            guiStyle_NotSelectable.normal.textColor = Color.red;
            guiStyle_NotSelectable.alignment        = TextAnchor.MiddleLeft;


            GUIStyle guiStyle_Center = new GUIStyle(GUIStyle.none);

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


            GUILayout.Space(10);

            _scrollList = EditorGUILayout.BeginScrollView(_scrollList, GUILayout.Width(width), GUILayout.Height(height_List));

            //"Presets"
            GUILayout.Button(new GUIContent(_editor.GetText(TEXT.DLG_Presets), _editor.ImageSet.Get(apImageSet.PRESET.Hierarchy_FoldDown)), guiStyle, GUILayout.Height(20));            //<투명 버튼

            for (int i = 0; i < _editor.ControlParamPreset.Presets.Count; i++)
            {
                //DrawBoneUnit(_boneUnits_Root[i], 0, width, iconImage_FoldDown, iconImage_FoldRight, guiContent_Bone, guiStyle, guiStyle_NotSelectable, _scrollList.x);
                DrawPresetUnit(_editor.ControlParamPreset.Presets[i], i, width - 18, _scrollList.x);
            }

            GUILayout.Space(310);

            EditorGUILayout.EndScrollView();

            EditorGUILayout.EndVertical();

            GUILayout.Space(10);

            //TODO : 선택된 객체 정보 + 삭제(Reserved 아닌 경우) + 적용과 취소
            int width_Info       = ((width - 10) / 2) - 10;
            int height_Info      = 150;
            int selectedIconSize = 40;

            if (_selectedUnit != null)
            {
                GUILayout.Box("[" + _selectedUnit._keyName + "]", boxGUIStyle, GUILayout.Width(width - 8), GUILayout.Height(30));

                //아이콘, 카테고리, 값 타입
                int rightInfoWidth = width - (selectedIconSize + 20);
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(selectedIconSize));
                Texture2D iconImage = _editor.ImageSet.Get(apEditorUtil.GetControlParamPresetIconType(_selectedUnit._iconPreset));
                GUILayout.Space(5);
                GUILayout.Box(iconImage, boxGUIStyle, GUILayout.Width(selectedIconSize), GUILayout.Height(selectedIconSize));

                GUILayout.Space(5);
                EditorGUILayout.BeginVertical(GUILayout.Width(rightInfoWidth), GUILayout.Height(selectedIconSize));

                //카테고리
                //값 타입
                GUILayout.Space(5);
                //"Category"
                EditorGUILayout.EnumPopup(_editor.GetText(TEXT.DLG_Category), _selectedUnit._category, GUILayout.Width(rightInfoWidth));
                //"Value Type"
                EditorGUILayout.EnumPopup(_editor.GetText(TEXT.DLG_ValueType), _selectedUnit._valueType, GUILayout.Width(rightInfoWidth));

                EditorGUILayout.EndVertical();
                EditorGUILayout.EndHorizontal();

                GUILayout.Space(5);



                //반반 나눠서 그려주자
                // Def    |  Label
                // Range  |  SnapSize

                int    bottomInfoWidth = width_Info - 10;
                string strValueDef     = "";
                string strLabel1       = "";
                string strLabel2       = "";

                int optLabelWidth  = 50;
                int optValueWidth  = bottomInfoWidth - (optLabelWidth + 10);
                int optValue2Width = (bottomInfoWidth - (optLabelWidth + 10)) / 2;

                switch (_selectedUnit._valueType)
                {
                case apControlParam.TYPE.Int:
                    strValueDef = _selectedUnit._int_Def.ToString();
                    //strLabel1 = "Min";
                    //strLabel2 = "Max";
                    strLabel1 = _editor.GetText(TEXT.DLG_Min);
                    strLabel2 = _editor.GetText(TEXT.DLG_Max);
                    break;

                case apControlParam.TYPE.Float:
                    strValueDef = _selectedUnit._float_Def.ToString();
                    //strLabel1 = "Min";
                    //strLabel2 = "Max";
                    strLabel1 = _editor.GetText(TEXT.DLG_Min);
                    strLabel2 = _editor.GetText(TEXT.DLG_Max);
                    break;

                case apControlParam.TYPE.Vector2:
                    strValueDef = _selectedUnit._vec2_Def.ToString();
                    //strLabel1 = "Axis 1";
                    //strLabel2 = "Axis 2";
                    strLabel1 = _editor.GetText(TEXT.DLG_Axis1);
                    strLabel2 = _editor.GetText(TEXT.DLG_Axis2);
                    break;
                }
                GUILayout.Space(5);

                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(height_Info));
                GUILayout.Space(5);
                EditorGUILayout.BeginVertical(GUILayout.Width(width_Info), GUILayout.Height(height_Info));

                //왼쪽 영역
                //기본 값
                //값 범위
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_ValueRange), GUILayout.Width(width_Info));                //"Value Range"
                GUILayout.Space(5);

                EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Default), GUILayout.Width(optLabelWidth));                //"Default"
                EditorGUILayout.TextField(strValueDef, GUILayout.Width(optValueWidth));
                EditorGUILayout.EndHorizontal();

                GUILayout.Space(5);


                switch (_selectedUnit._valueType)
                {
                case apControlParam.TYPE.Int:
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Min), GUILayout.Width(optLabelWidth));                            //"Min"
                    EditorGUILayout.IntField(_selectedUnit._int_Min, GUILayout.Width(optValueWidth));
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Max), GUILayout.Width(optLabelWidth));                            //"Max"
                    EditorGUILayout.IntField(_selectedUnit._int_Max, GUILayout.Width(optValueWidth));
                    EditorGUILayout.EndHorizontal();
                    break;

                case apControlParam.TYPE.Float:
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Min), GUILayout.Width(optLabelWidth));                            //"Min"
                    EditorGUILayout.FloatField(_selectedUnit._float_Min, GUILayout.Width(optValueWidth));
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(width_Info));
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Max), GUILayout.Width(optLabelWidth));                            //"Max"
                    EditorGUILayout.FloatField(_selectedUnit._float_Max, GUILayout.Width(optValueWidth));
                    EditorGUILayout.EndHorizontal();
                    break;

                case apControlParam.TYPE.Vector2:
                {
                    EditorGUILayout.BeginHorizontal(GUILayout.Width(bottomInfoWidth));
                    EditorGUILayout.LabelField("", GUILayout.Width(optLabelWidth));
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Min), GUILayout.Width(optValue2Width));                                    //"Min"
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Max), GUILayout.Width(optValue2Width));                                    //"Max"
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(bottomInfoWidth));
                    EditorGUILayout.LabelField("X", GUILayout.Width(optLabelWidth));
                    EditorGUILayout.FloatField(_selectedUnit._vec2_Min.x, GUILayout.Width(optValue2Width));
                    EditorGUILayout.FloatField(_selectedUnit._vec2_Max.x, GUILayout.Width(optValue2Width));
                    EditorGUILayout.EndHorizontal();

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(bottomInfoWidth));
                    EditorGUILayout.LabelField("Y", GUILayout.Width(optLabelWidth));
                    EditorGUILayout.FloatField(_selectedUnit._vec2_Min.y, GUILayout.Width(optValue2Width));
                    EditorGUILayout.FloatField(_selectedUnit._vec2_Max.y, GUILayout.Width(optValue2Width));
                    EditorGUILayout.EndHorizontal();
                }

                break;
                }

                EditorGUILayout.EndVertical();

                GUILayout.Space(4);

                EditorGUILayout.BeginVertical(GUILayout.Width(width_Info), GUILayout.Height(height_Info));

                //오른쪽 영역
                //Label
                //SnapSize
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Label), GUILayout.Width(bottomInfoWidth));                //"Label"
                GUILayout.Space(5);
                EditorGUILayout.BeginHorizontal(GUILayout.Width(bottomInfoWidth));
                EditorGUILayout.LabelField(strLabel1, GUILayout.Width(optLabelWidth));
                EditorGUILayout.TextField(_selectedUnit._label_Min, GUILayout.Width(optValueWidth));
                EditorGUILayout.EndHorizontal();

                EditorGUILayout.BeginHorizontal(GUILayout.Width(bottomInfoWidth));
                EditorGUILayout.LabelField(strLabel2, GUILayout.Width(optLabelWidth));
                EditorGUILayout.TextField(_selectedUnit._label_Max, GUILayout.Width(optValueWidth));
                EditorGUILayout.EndHorizontal();


                GUILayout.Space(5);
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_SnapSize), GUILayout.Width(bottomInfoWidth));                //"Snap Size"
                EditorGUILayout.IntField(_selectedUnit._snapSize, GUILayout.Width(bottomInfoWidth));


                //Reserved가 아니면 삭제가능
                if (!_selectedUnit._isReserved)
                {
                    //"Remove Preset"
                    if (GUILayout.Button(_editor.GetText(TEXT.DLG_RemovePreset), GUILayout.Height(25)))
                    {
                        bool result = EditorUtility.DisplayDialog(_editor.GetText(TEXT.ControlParamPreset_Remove_Title),
                                                                  _editor.GetTextFormat(TEXT.ControlParamPreset_Remove_Body, _selectedUnit._keyName),
                                                                  _editor.GetText(TEXT.Remove),
                                                                  _editor.GetText(TEXT.Cancel));

                        if (result)
                        {
                            int targetID = _selectedUnit._uniqueID;
                            _selectedUnit = null;

                            _editor.ControlParamPreset.RemovePreset(targetID);
                        }
                    }
                }

                EditorGUILayout.EndVertical();
                EditorGUILayout.EndHorizontal();
            }
            else
            {
                //"No Selected"
                GUILayout.Box(_editor.GetText(TEXT.DLG_NotSelected), boxGUIStyle, GUILayout.Width(width - 8), GUILayout.Height(30));

                GUILayout.Space(height_Info + selectedIconSize + 14);
            }

            bool isClose = false;
            bool isSelectBtnAvailable = _selectedUnit != null;

            EditorGUILayout.BeginHorizontal();
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Apply), false, isSelectBtnAvailable, (width / 2) - 8, 30))            //"Apply"
            {
                _funcResult(true, _loadKey, _selectedUnit, _targetControlParam);
                isClose = true;
            }
            if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_Close), false, true, (width / 2) - 8, 30))            //"Close"
            {
                //_funcResult(false, _loadKey, null, null);
                _funcResult(false, _loadKey, null, _targetControlParam);
                isClose = true;
            }
            EditorGUILayout.EndHorizontal();

            if (isClose)
            {
                CloseDialog();
            }
        }
示例#6
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);
        }
        void OnGUI()
        {
            int width  = (int)position.width;
            int height = (int)position.height;

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

            try
            {
                Color prevColor = GUI.backgroundColor;

                //레이아웃 구조
                // 타이틀
                // Pose 리스트 경로 + 변경 + 갱신
                // Pose 보기 종류 : 동일 MeshGroup만, 동일 Portrait만, 모든 Scene에서의 Pose 기록 (Import 안될 수도 있음)
                // Pose 리스트
                // 선택한 Pose 정보
                // Pose 이름, 설명
                // 저장된 Bone 이름들 (최대 4개 보여주기)
                // Import / Close

                width -= 10;

                //1. 다이얼로그 타이틀
                GUIStyle guiStyleBox = new GUIStyle(GUI.skin.box);
                guiStyleBox.alignment        = TextAnchor.MiddleCenter;
                guiStyleBox.normal.textColor = apEditorUtil.BoxTextColor;

                GUIStyle guiStyleBox_Left = new GUIStyle(GUI.skin.textField);
                guiStyleBox_Left.alignment = TextAnchor.MiddleLeft;

                //"  Import Pose"
                GUILayout.Box(new GUIContent("  " + _editor.GetText(TEXT.DLG_ImportPose), _editor.ImageSet.Get(apImageSet.PRESET.Rig_LoadBones)), guiStyleBox, GUILayout.Width(width), GUILayout.Height(35));
                GUILayout.Space(5);

                //2. Pose 리스트 경로 + 변경 + 갱신
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(20));
                int changeBtnWidth  = 70;
                int refreshBtnWidth = 80;
                int pathWidth       = width - (changeBtnWidth + refreshBtnWidth + 4 + 10);

                GUILayout.Space(5);
                EditorGUILayout.TextField(_editor._bonePose_BaseFolderName, GUILayout.Width(pathWidth), GUILayout.Height(20));

                //"Change"
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Change), GUILayout.Width(changeBtnWidth), GUILayout.Height(20)))
                {
                    string pathResult = EditorUtility.SaveFolderPanel("Set the Pose Folder", _editor._bonePose_BaseFolderName, "");
                    if (!string.IsNullOrEmpty(pathResult))
                    {
                        Uri targetUri = new Uri(pathResult);
                        Uri baseUri   = new Uri(Application.dataPath);

                        string relativePath = baseUri.MakeRelativeUri(targetUri).ToString();

                        _editor._bonePose_BaseFolderName = relativePath;

                        apEditorUtil.SetEditorDirty();

                        _editor.SaveEditorPref();

                        _retarget.LoadSinglePoseFileList(_editor);
                        _selectedBonePoseFile = null;
                        _isValidPose          = false;
                    }
                }
                //"Refresh"
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Refresh), GUILayout.Width(refreshBtnWidth), GUILayout.Height(20)))
                {
                    _retarget.LoadSinglePoseFileList(_editor);
                    _selectedBonePoseFile = null;
                    _isValidPose          = false;
                }

                EditorGUILayout.EndHorizontal();

                GUILayout.Space(5);

                //3. Pose 보기 종류
                int categoryBtnWidth  = (width - 10) / 3 - 1;
                int categoryBtnHeight = 20;
                EditorGUILayout.BeginHorizontal(GUILayout.Width(width), GUILayout.Height(categoryBtnHeight));
                GUILayout.Space(5);

                //"Same MeshGroup"
                if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_SameGroup), _category == CATEGORY.SameMeshGroup, true, categoryBtnWidth, categoryBtnHeight))
                {
                    _category             = CATEGORY.SameMeshGroup;
                    _selectedBonePoseFile = null;
                    _isValidPose          = false;
                }

                //"Same Portrait"
                if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_SamePortrait), _category == CATEGORY.SamePortrait, true, categoryBtnWidth, categoryBtnHeight))
                {
                    _category             = CATEGORY.SamePortrait;
                    _selectedBonePoseFile = null;
                    _isValidPose          = false;
                }

                //"All Poses"
                if (apEditorUtil.ToggledButton(_editor.GetText(TEXT.DLG_AllPoses), _category == CATEGORY.AllPoses, true, categoryBtnWidth, categoryBtnHeight))
                {
                    _category             = CATEGORY.AllPoses;
                    _selectedBonePoseFile = null;
                    _isValidPose          = false;
                }

                EditorGUILayout.EndHorizontal();

                GUILayout.Space(5);

                //4. Pose 리스트
                int listHeight = height - 450;

                Rect lastRect = GUILayoutUtility.GetLastRect();

                GUI.backgroundColor = new Color(0.9f, 0.9f, 0.9f);
                GUI.Box(new Rect(0, lastRect.y + 5, width + 10, listHeight), "");

                List <apRetargetPoseListFile.FileMetaData> metaDataList = _retarget.SinglePoseList._metaDataList;

                int itemWidth  = width - 20;
                int itemHeight = 20;

                int poseNameWidth      = 120;
                int portraitNameWidth  = 100;
                int meshGroupNameWidth = 100;
                int selectBtnWidth     = (width - 40) - (poseNameWidth + portraitNameWidth + meshGroupNameWidth + 6);

                GUIStyle guiStyle_ItemLabel = new GUIStyle(GUI.skin.label);
                guiStyle_ItemLabel.alignment = TextAnchor.MiddleLeft;

                GUIStyle guiStyle_ItemCategory = new GUIStyle(GUI.skin.label);
                //guiStyle_ItemCategory.alignment = TextAnchor.MiddleCenter;
                if (EditorGUIUtility.isProSkin)
                {
                    guiStyle_ItemCategory.normal.textColor = Color.cyan;
                }
                else
                {
                    guiStyle_ItemCategory.normal.textColor = Color.blue;
                }


                _scrollList = EditorGUILayout.BeginScrollView(_scrollList, false, true, GUILayout.Width(width + 10), GUILayout.Height(listHeight));
                EditorGUILayout.BeginVertical(GUILayout.Width(width - 10));

                if (!_retarget.SinglePoseList._isFolderExist)
                {
                    //"Pose Folder does not exist."
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_PoseFolderNotExist), GUILayout.Width(itemWidth));
                }
                else
                {
                    //Pose 이름 / Portrait 이름 / MeshGroup 이름 / 선택

                    EditorGUILayout.BeginHorizontal(GUILayout.Width(itemWidth), GUILayout.Height(itemHeight));
                    GUILayout.Space(5);

                    //"Name"
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Name), guiStyle_ItemCategory, GUILayout.Width(poseNameWidth), GUILayout.Height(itemHeight));

                    //"Portrait"
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Portrait), guiStyle_ItemCategory, GUILayout.Width(portraitNameWidth), GUILayout.Height(itemHeight));

                    //"Mesh Group"
                    EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_MeshGroup), guiStyle_ItemCategory, GUILayout.Width(meshGroupNameWidth), GUILayout.Height(itemHeight));
                    EditorGUILayout.EndHorizontal();

                    GUILayout.Space(10);

                    apRetargetPoseListFile.FileMetaData metaData = null;
                    for (int i = 0; i < metaDataList.Count; i++)
                    {
                        metaData = metaDataList[i];

                        if (_category == CATEGORY.AllPoses)
                        {
                            //그냥 통과
                        }
                        else if (_category == CATEGORY.SamePortrait)
                        {
                            if (!string.Equals(_portraitName, metaData._portraitName))
                            {
                                //Portrait 이름이 다르면 스킵
                                continue;
                            }
                        }
                        else if (_category == CATEGORY.SameMeshGroup)
                        {
                            if (!string.Equals(_portraitName, metaData._portraitName) ||
                                _meshGroupUniqueID != metaData._meshGroupUniqueID)
                            {
                                //Portrait 이름이 다르거나 MeshGroupUniqueID가 다르다면 스킵
                                continue;
                            }
                        }

                        EditorGUILayout.BeginHorizontal(GUILayout.Width(itemWidth), GUILayout.Height(itemHeight));
                        GUILayout.Space(5);
                        EditorGUILayout.LabelField(metaData._poseName, guiStyle_ItemLabel, GUILayout.Width(poseNameWidth), GUILayout.Height(itemHeight));
                        EditorGUILayout.LabelField(metaData._portraitName, guiStyle_ItemLabel, GUILayout.Width(portraitNameWidth), GUILayout.Height(itemHeight));
                        EditorGUILayout.LabelField(metaData._meshGroupName, guiStyle_ItemLabel, GUILayout.Width(meshGroupNameWidth), GUILayout.Height(itemHeight));

                        //"Selected", "Select"
                        if (apEditorUtil.ToggledButton_2Side(_editor.GetText(TEXT.DLG_Selected),
                                                             _editor.GetText(TEXT.DLG_Select), metaData == _selectedBonePoseFile, true, selectBtnWidth, itemHeight))
                        {
                            _selectedBonePoseFile = metaData;

                            _isValidPose = string.Equals(_portraitName, metaData._portraitName) &&
                                           _meshGroupUniqueID == metaData._meshGroupUniqueID;
                        }
                        EditorGUILayout.EndHorizontal();
                    }
                }

                EditorGUILayout.EndVertical();
                GUILayout.Space(listHeight + 100);

                EditorGUILayout.EndScrollView();

                GUILayout.Space(10);
                //정보를 출력한다.
                //Pose 이름
                //설명
                //Portrait
                //MeshGroup
                //MeshGroup이 다르면 경고를 준다.
                //Bone 개수와 이름들
                //string selectedPoseName = "No Pose Selected";
                string selectedPoseName      = _editor.GetText(TEXT.DLG_NoPoseSelected);
                string selectedDesc          = "";
                string selectedPortrait      = "";
                string selectedMeshGroupName = "";
                int    boneCount             = 0;
                string selectedBoneNames     = "";

                if (_selectedBonePoseFile != null)
                {
                    selectedPoseName      = _selectedBonePoseFile._poseName;
                    selectedDesc          = _selectedBonePoseFile._description;
                    selectedPortrait      = _selectedBonePoseFile._portraitName;
                    selectedMeshGroupName = _selectedBonePoseFile._meshGroupName;
                    boneCount             = _selectedBonePoseFile._nBones;
                    selectedBoneNames     = _selectedBonePoseFile._boneNames;
                }

                GUIStyle guiStyle_Desc = new GUIStyle(GUI.skin.textField);
                guiStyle_Desc.wordWrap = true;

                if (_selectedBonePoseFile != null)
                {
                    GUI.backgroundColor = new Color(GUI.backgroundColor.r * 1.0f, GUI.backgroundColor.g * 1.8f, GUI.backgroundColor.b * 1.2f, 1.0f);
                }
                GUILayout.Box(selectedPoseName, guiStyleBox, GUILayout.Width(width), GUILayout.Height(30));
                if (_selectedBonePoseFile != null)
                {
                    GUI.backgroundColor = prevColor;
                }

                //"Description"
                EditorGUILayout.LabelField(_editor.GetText(TEXT.DLG_Description), GUILayout.Width(width));
                EditorGUILayout.LabelField(selectedDesc, guiStyle_Desc, GUILayout.Width(width), GUILayout.Height(45));

                GUILayout.Space(5);

                EditorGUILayout.LabelField(string.Format("{0} : {1}", _editor.GetText(TEXT.DLG_Portrait), selectedPortrait), GUILayout.Width(width));            //"Portrait : "
                EditorGUILayout.LabelField(string.Format("{0} : {1}", _editor.GetText(TEXT.DLG_MeshGroup), selectedMeshGroupName), GUILayout.Width(width));      //"Mesh Group : "
                GUILayout.Space(5);
                EditorGUILayout.LabelField(string.Format("{0} : {1}", _editor.GetText(TEXT.DLG_NumberBones), boneCount), GUILayout.Width(width));                //"Number of Bones : "

                if (_selectedBonePoseFile == null)
                {
                    //"No Bones"
                    GUILayout.Box(_editor.GetText(TEXT.DLG_NoBones), GUILayout.Width(width), GUILayout.Height(45));
                }
                else
                {
                    if (_isValidPose)
                    {
                        GUI.backgroundColor = new Color(GUI.backgroundColor.r * 1.0f, GUI.backgroundColor.g * 1.5f, GUI.backgroundColor.b * 1.2f, 1.0f);
                        GUILayout.Box(selectedBoneNames, guiStyleBox, GUILayout.Width(width), GUILayout.Height(45));
                        GUI.backgroundColor = prevColor;
                    }
                    else
                    {
                        GUI.backgroundColor = new Color(GUI.backgroundColor.r * 1.5f, GUI.backgroundColor.g * 0.7f, GUI.backgroundColor.b * 0.7f, 1.0f);
                        //"[Warning. Import may not work properly]\n" + selectedBoneNames
                        GUILayout.Box(string.Format("[{0}]\n{1}", _editor.GetText(TEXT.DLG_Warningproperly), selectedBoneNames), guiStyleBox, GUILayout.Width(width), GUILayout.Height(45));
                        GUI.backgroundColor = prevColor;
                    }
                }

                //"Remove Pose", "Remove Pose"
                if (apEditorUtil.ToggledButton_2Side(_editor.GetText(TEXT.DLG_RemovePose), _editor.GetText(TEXT.DLG_RemovePose), false, _selectedBonePoseFile != null, width, 20))
                {
                    bool isResult = EditorUtility.DisplayDialog(_editor.GetText(TEXT.Retarget_RemoveSinglePose_Title),
                                                                _editor.GetTextFormat(TEXT.Retarget_RemoveSinglePose_Body, selectedPoseName),
                                                                _editor.GetText(TEXT.Remove), _editor.GetText(TEXT.Cancel)
                                                                );

                    if (isResult && _selectedBonePoseFile != null)
                    {
                        _retarget.SinglePoseList.RemoveFile(_selectedBonePoseFile);

                        //리스트 갱신
                        _retarget.LoadSinglePoseFileList(_editor);
                        _selectedBonePoseFile = null;
                        _isValidPose          = false;
                    }
                }

                string strImportPose = " " + _editor.GetText(TEXT.DLG_ImportPose);
                GUILayout.Space(10);

                //" Import Pose", " Import Pose"
                if (apEditorUtil.ToggledButton_2Side(_editor.ImageSet.Get(apImageSet.PRESET.Rig_LoadBones),
                                                     strImportPose, strImportPose, false, _selectedBonePoseFile != null, width, 30))
                {
                    //1. Retarget Bone Pose에 선택한 MetaData 정보를 넣자
                    if (_selectedBonePoseFile != null)
                    {
                        bool isSuccess = _retarget.LoadSinglePose(_selectedBonePoseFile._filePath);

                        if (!isSuccess)
                        {
                            EditorUtility.DisplayDialog(_editor.GetText(TEXT.Retarget_SinglePoseImportFailed_Title),
                                                        _editor.GetText(TEXT.Retarget_SinglePoseImportFailed_Body_Error),
                                                        _editor.GetText(TEXT.Close));
                        }
                        else
                        {
                            //2. 리턴 함수 콜
                            if (_funcResult_Anim != null)
                            {
                                _funcResult_Anim(_loadKey, true, _retarget, _targetMeshGroup, _targetAnimClip, _targetAnimTimeline, _targetFrame);
                            }
                            else if (_funcResult_Mod != null)
                            {
                                _funcResult_Mod(_loadKey, true, _retarget, _targetMeshGroup, _targetModifier, _targetParamSet);
                            }

                            //3. 창 닫기
                            CloseDialog();
                        }
                    }
                    else
                    {
                        EditorUtility.DisplayDialog(_editor.GetText(TEXT.Retarget_SinglePoseImportFailed_Title),
                                                    _editor.GetText(TEXT.Retarget_SinglePoseImportFailed_Body_NoFile),
                                                    _editor.GetText(TEXT.Close));
                    }
                }

                //"Close"
                if (GUILayout.Button(_editor.GetText(TEXT.DLG_Close), GUILayout.Width(width), GUILayout.Height(25)))
                {
                    if (_funcResult_Anim != null)
                    {
                        _funcResult_Anim(null, false, _retarget, _targetMeshGroup, _targetAnimClip, _targetAnimTimeline, _targetFrame);
                    }
                    else if (_funcResult_Mod != null)
                    {
                        _funcResult_Mod(null, false, _retarget, _targetMeshGroup, _targetModifier, _targetParamSet);
                    }

                    CloseDialog();
                }
            }
            catch (Exception)
            {
            }
        }