public void SetSortingOrderOption(apPortrait.SORTING_ORDER_OPTION sortingOrderOption) { if (_sortedRenderBuffer == null) { return; } _sortedRenderBuffer.SetSortingOrderOption(sortingOrderOption); }
// Bake //---------------------------------------------------------- //Render Buffer는 Bake가 3단계로 이루어진다. //데이터가 절차적으로 생성되는 바람에.. 어쩔 수 없이... 힁 public void Bake_Init(apPortrait portrait, apOptRootUnit rootUnit, apRootUnit srcRootUnit) { Clear(); _bakedBuffers.Clear(); _ZPerDepth = portrait._bakeZSize; _sortingOrderOption = portrait._sortingOrderOption; //추가 19.8.19 SetSortingOrderChangedAutomatically(true); }
public void SetSortingOrderOption(apPortrait.SORTING_ORDER_OPTION sortingOrderOption) { _sortingOrderOption = sortingOrderOption; }
// 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); }
public override void OnInspectorGUI() { //return; LoadImages(); //base.OnInspectorGUI(); apPortrait targetPortrait = target as apPortrait; if (targetPortrait != _targetPortrait) { _targetPortrait = targetPortrait; Init(); } if (_targetPortrait == null) { //Profiler.EndSample(); return; } //Profiler.BeginSample("anyPortrait Inspector GUI"); //return; if (apEditor.IsOpen()) { //에디터가 작동중에는 안보이도록 하자 //EditorGUILayout.LabelField("Editor is opened"); GUILayout.Space(10); EditorGUILayout.LabelField(_guiContent_EditorIsOpen, GUILayout.Height(36)); //Profiler.EndSample(); return; } try { bool request_OpenEditor = false; bool request_QuickBake = false; bool request_RefreshMeshes = false; bool prevImportant = _targetPortrait._isImportant; MonoBehaviour prevAnimEventListener = _targetPortrait._optAnimEventListener; int prevSortingLayerID = _targetPortrait._sortingLayerID; apPortrait.SORTING_ORDER_OPTION prevSortingOrderOption = _targetPortrait._sortingOrderOption; int prevSortingOrder = _targetPortrait._sortingOrder; if (!EditorApplication.isPlaying) { int iconWidth = 32; int iconHeight = 34; int buttonHeight = 34; //추가 19.5.26 : 용량 최적화 기능이 추가되었는가 if (!_targetPortrait._isSizeOptimizedV117) { GUILayout.Space(10); Color prevBackColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1.0f, 0.7f, 0.7f, 1.0f); GUILayout.Box("[File size reduction] has not been applied.\nExecute the [Bake] again.", _guiStyle_subTitle, GUILayout.Width((int)EditorGUIUtility.currentViewWidth - 36), GUILayout.Height(40)); GUI.backgroundColor = prevBackColor; } if (!_targetPortrait._isOptimizedPortrait) { GUILayout.Space(10); EditorGUILayout.BeginHorizontal(GUILayout.Height(iconHeight)); GUILayout.Space(5); EditorGUILayout.LabelField(_guiContent_OpenEditor, _guiStyle_buttonIcon, GUILayout.Width(iconWidth), GUILayout.Height(iconHeight)); GUILayout.Space(5); if (GUILayout.Button("Open Editor and Select", GUILayout.Height(buttonHeight))) { request_OpenEditor = true; } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(GUILayout.Height(iconHeight)); GUILayout.Space(5); EditorGUILayout.LabelField(_guiContent_QuickBake, _guiStyle_buttonIcon, GUILayout.Width(iconWidth), GUILayout.Height(iconHeight)); GUILayout.Space(5); if (GUILayout.Button("Quick Bake", GUILayout.Height(buttonHeight))) { request_QuickBake = true; } EditorGUILayout.EndHorizontal(); } else { GUILayout.Space(10); EditorGUILayout.BeginHorizontal(GUILayout.Height(iconHeight)); GUILayout.Space(5); EditorGUILayout.LabelField(_guiContent_OpenEditor, _guiStyle_buttonIcon, GUILayout.Width(iconWidth), GUILayout.Height(iconHeight)); GUILayout.Space(5); if (GUILayout.Button("Open Editor (Not Selectable)", GUILayout.Height(buttonHeight))) { //열기만 하고 선택은 못함 request_OpenEditor = true; } EditorGUILayout.EndHorizontal(); } //추가 12.18 : Mesh를 리프레시 하자 EditorGUILayout.BeginHorizontal(GUILayout.Height(iconHeight)); GUILayout.Space(5); EditorGUILayout.LabelField(_guiContent_RefreshMeshes, _guiStyle_buttonIcon, GUILayout.Width(iconWidth), GUILayout.Height(iconHeight)); GUILayout.Space(5); if (GUILayout.Button("Refresh Meshes", GUILayout.Height(buttonHeight))) { request_RefreshMeshes = true; } EditorGUILayout.EndHorizontal(); } GUILayout.Space(10); //BasicSettings //----------------------------------------------------------------------------- //"Basic Settings" int width = (int)EditorGUIUtility.currentViewWidth; int subTitleWidth = width - 44; int subTitleHeight = 26; GUILayout.Box(_guiContent_BasicSettings, _guiStyle_subTitle, GUILayout.Width(subTitleWidth), GUILayout.Height(subTitleHeight)); _targetPortrait._isImportant = EditorGUILayout.Toggle("Is Important", _targetPortrait._isImportant); _targetPortrait._optAnimEventListener = (MonoBehaviour)EditorGUILayout.ObjectField("Event Listener", _targetPortrait._optAnimEventListener, typeof(MonoBehaviour), true); GUILayout.Space(5); //추가3.22 //Sorting Layer string[] sortingLayerName = new string[SortingLayer.layers.Length]; int layerIndex = -1; for (int i = 0; i < SortingLayer.layers.Length; i++) { sortingLayerName[i] = SortingLayer.layers[i].name; if (SortingLayer.layers[i].id == _targetPortrait._sortingLayerID) { layerIndex = i; } } int nextLayerIndex = EditorGUILayout.Popup("Sorting Layer", layerIndex, sortingLayerName); apPortrait.SORTING_ORDER_OPTION nextSortingOption = (apPortrait.SORTING_ORDER_OPTION)EditorGUILayout.EnumPopup("Sorting Order Option", _targetPortrait._sortingOrderOption); int nextLayerOrder = _targetPortrait._sortingOrder; if (_targetPortrait._sortingOrderOption == apPortrait.SORTING_ORDER_OPTION.SetOrder) { nextLayerOrder = EditorGUILayout.IntField("Sorting Order", _targetPortrait._sortingOrder); if (nextLayerOrder != _targetPortrait._sortingOrder) { _targetPortrait.SetSortingOrder(nextLayerOrder); } } if (nextLayerIndex != layerIndex) { //Sorting Layer를 바꾸자 if (nextLayerIndex >= 0 && nextLayerIndex < SortingLayer.layers.Length) { string nextLayerName = SortingLayer.layers[nextLayerIndex].name; _targetPortrait.SetSortingLayer(nextLayerName); } } if (nextSortingOption != _targetPortrait._sortingOrderOption) { _targetPortrait._sortingOrderOption = nextSortingOption; //변경된 Sorting Order Option에 따라서 바로 Sorting을 해야한다. _targetPortrait.ApplySortingOptionToOptRootUnits(); switch (_targetPortrait._sortingOrderOption) { case apPortrait.SORTING_ORDER_OPTION.SetOrder: _targetPortrait.SetSortingOrder(_targetPortrait._sortingOrder); break; case apPortrait.SORTING_ORDER_OPTION.DepthToOrder: case apPortrait.SORTING_ORDER_OPTION.ReverseDepthToOrder: _targetPortrait.SetSortingOrderChangedAutomatically(true); _targetPortrait.RefreshSortingOrderByDepth(); break; } } if (prevImportant != _targetPortrait._isImportant || prevAnimEventListener != _targetPortrait._optAnimEventListener || prevSortingLayerID != _targetPortrait._sortingLayerID || prevSortingOrderOption != _targetPortrait._sortingOrderOption || prevSortingOrder != _targetPortrait._sortingOrder) { apEditorUtil.SetEditorDirty(); } GUILayout.Space(5); //빌보드 apPortrait.BILLBOARD_TYPE nextBillboard = (apPortrait.BILLBOARD_TYPE)EditorGUILayout.EnumPopup("Billboard Type", _targetPortrait._billboardType); if (nextBillboard != _targetPortrait._billboardType) { _targetPortrait._billboardType = nextBillboard; apEditorUtil.SetEditorDirty(); } GUILayout.Space(20); // Root Portraits //----------------------------------------------------------------------------- GUILayout.Box(_guiContent_RootPortraits, _guiStyle_subTitle, GUILayout.Width(subTitleWidth), GUILayout.Height(subTitleHeight)); _isFold_RootPortraits = EditorGUILayout.Foldout(_isFold_RootPortraits, "Portraits"); if (_isFold_RootPortraits) { for (int i = 0; i < _targetPortrait._optRootUnitList.Count; i++) { apOptRootUnit rootUnit = _targetPortrait._optRootUnitList[i]; EditorGUILayout.ObjectField("[" + i + "]", rootUnit, typeof(apOptRootUnit), true); } } GUILayout.Space(20); // Animation Settings //----------------------------------------------------------------------------- GUILayout.Box(_guiContent_AnimationSettings, _guiStyle_subTitle, GUILayout.Width(subTitleWidth), GUILayout.Height(subTitleHeight)); _isFold_AnimationClips = EditorGUILayout.Foldout(_isFold_AnimationClips, "Animation Clips"); if (_isFold_AnimationClips) { for (int i = 0; i < _targetPortrait._animClips.Count; i++) { EditorGUILayout.BeginHorizontal(); GUILayout.Space(5); apAnimClip animClip = _targetPortrait._animClips[i]; if (animClip._uniqueID == _targetPortrait._autoPlayAnimClipID) { EditorGUILayout.LabelField("[" + i + "] (Auto)", GUILayout.Width(80)); } else { EditorGUILayout.LabelField("[" + i + "]", GUILayout.Width(80)); } EditorGUILayout.TextField(animClip._name); try { AnimationClip nextAnimationClip = EditorGUILayout.ObjectField(animClip._animationClipForMecanim, typeof(AnimationClip), false) as AnimationClip; if (nextAnimationClip != animClip._animationClipForMecanim) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Animation Changed"); animClip._animationClipForMecanim = nextAnimationClip; } } catch (Exception) { } EditorGUILayout.EndHorizontal(); } } GUILayout.Space(10); AnimationClip nextEmptyAnimClip = EditorGUILayout.ObjectField("Empty Anim Clip", _targetPortrait._emptyAnimClipForMecanim, typeof(AnimationClip), false) as AnimationClip; if (nextEmptyAnimClip != _targetPortrait._emptyAnimClipForMecanim) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Animation Changed"); _targetPortrait._emptyAnimClipForMecanim = nextEmptyAnimClip; } GUILayout.Space(10); //EditorGUILayout.LabelField("Mecanim Settings"); EditorGUILayout.LabelField(_guiContent_Mecanim, GUILayout.Height(24)); bool isNextUsingMecanim = EditorGUILayout.Toggle("Use Mecanim", _targetPortrait._isUsingMecanim); if (_targetPortrait._isUsingMecanim != isNextUsingMecanim) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Mecanim Setting Changed"); _targetPortrait._isUsingMecanim = isNextUsingMecanim; } if (_targetPortrait._isUsingMecanim) { //GUILayout.Space(10); try { Animator nextAnimator = EditorGUILayout.ObjectField("Animator", _targetPortrait._animator, typeof(Animator), true) as Animator; if (nextAnimator != _targetPortrait._animator) { //하위에 있는 Component일 때에만 변동 가능 if (nextAnimator == null) { _targetPortrait._animator = null; } else { if (nextAnimator == _targetPortrait.GetComponent <Animator>()) { _targetPortrait._animator = nextAnimator; } else { EditorUtility.DisplayDialog("Invalid Animator", "Invalid Animator. Only the Animator, which is its own component, is valid.", "Okay"); } } } } catch (Exception) { } if (_targetPortrait._animator == null) { //1. Animator가 없다면 // > 생성하기 // > 생성되어 있다면 다시 링크 GUIStyle guiStyle_WarningText = new GUIStyle(GUI.skin.label); guiStyle_WarningText.normal.textColor = Color.red; EditorGUILayout.LabelField("Warning : No Animator!", guiStyle_WarningText); GUILayout.Space(5); if (GUILayout.Button("Add / Check Animator", GUILayout.Height(25))) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Mecanim Setting Changed"); Animator animator = _targetPortrait.gameObject.GetComponent <Animator>(); if (animator == null) { animator = _targetPortrait.gameObject.AddComponent <Animator>(); } _targetPortrait._animator = animator; } } else { //2. Animator가 있다면 if (GUILayout.Button("Refresh Layers", GUILayout.Height(25))) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Mecanim Setting Changed"); //Animator의 Controller가 있는지 체크해야한다. if (_targetPortrait._animator.runtimeAnimatorController == null) { //AnimatorController가 없다면 Layer는 초기화 _targetPortrait._animatorLayerBakedData.Clear(); } else { //AnimatorController가 있다면 레이어에 맞게 설정 _targetPortrait._animatorLayerBakedData.Clear(); UnityEditor.Animations.AnimatorController animatorController = _targetPortrait._animator.runtimeAnimatorController as UnityEditor.Animations.AnimatorController; if (animatorController != null && animatorController.layers.Length > 0) { for (int iLayer = 0; iLayer < animatorController.layers.Length; iLayer++) { apAnimMecanimData_Layer newLayerData = new apAnimMecanimData_Layer(); newLayerData._layerIndex = iLayer; newLayerData._layerName = animatorController.layers[iLayer].name; newLayerData._blendType = apAnimMecanimData_Layer.MecanimLayerBlendType.Unknown; switch (animatorController.layers[iLayer].blendingMode) { case UnityEditor.Animations.AnimatorLayerBlendingMode.Override: newLayerData._blendType = apAnimMecanimData_Layer.MecanimLayerBlendType.Override; break; case UnityEditor.Animations.AnimatorLayerBlendingMode.Additive: newLayerData._blendType = apAnimMecanimData_Layer.MecanimLayerBlendType.Additive; break; } _targetPortrait._animatorLayerBakedData.Add(newLayerData); } } } } GUILayout.Space(5); EditorGUILayout.LabelField("Animator Controller Layers"); for (int i = 0; i < _targetPortrait._animatorLayerBakedData.Count; i++) { apAnimMecanimData_Layer layer = _targetPortrait._animatorLayerBakedData[i]; EditorGUILayout.BeginHorizontal(); GUILayout.Space(5); EditorGUILayout.LabelField("[" + layer._layerIndex + "]", GUILayout.Width(50)); EditorGUILayout.TextField(layer._layerName); apAnimMecanimData_Layer.MecanimLayerBlendType nextBlendType = (apAnimMecanimData_Layer.MecanimLayerBlendType)EditorGUILayout.EnumPopup(layer._blendType); EditorGUILayout.EndHorizontal(); if (nextBlendType != layer._blendType) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Mecanim Setting Changed"); _targetPortrait._animatorLayerBakedData[i]._blendType = nextBlendType; } } } } GUILayout.Space(20); //추가 3.4 : 타임라인 설정 #if UNITY_2017_1_OR_NEWER EditorGUILayout.LabelField(_guiContent_Timeline, GUILayout.Height(24)); _isFold_Timeline = EditorGUILayout.Foldout(_isFold_Timeline, "Track Data"); if (_isFold_Timeline) { int nextTimelineTracks = EditorGUILayout.DelayedIntField("Size", _nTimelineTrackSet); if (nextTimelineTracks != _nTimelineTrackSet) { //TimelineTrackSet의 개수가 바뀌었다. UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Track Setting Changed"); _nTimelineTrackSet = nextTimelineTracks; if (_nTimelineTrackSet < 0) { _nTimelineTrackSet = 0; } //일단 이전 개수만큼 복사를 한다. int nPrev = 0; List <apPortrait.TimelineTrackPreset> prevSets = new List <apPortrait.TimelineTrackPreset>(); if (targetPortrait._timelineTrackSets != null && targetPortrait._timelineTrackSets.Length > 0) { for (int i = 0; i < targetPortrait._timelineTrackSets.Length; i++) { prevSets.Add(targetPortrait._timelineTrackSets[i]); } nPrev = targetPortrait._timelineTrackSets.Length; } //배열을 새로 만들자 targetPortrait._timelineTrackSets = new apPortrait.TimelineTrackPreset[_nTimelineTrackSet]; //가능한 이전 소스를 복사한다. for (int i = 0; i < _nTimelineTrackSet; i++) { if (i < nPrev) { targetPortrait._timelineTrackSets[i] = new apPortrait.TimelineTrackPreset(); targetPortrait._timelineTrackSets[i]._playableDirector = prevSets[i]._playableDirector; targetPortrait._timelineTrackSets[i]._trackName = prevSets[i]._trackName; targetPortrait._timelineTrackSets[i]._layer = prevSets[i]._layer; targetPortrait._timelineTrackSets[i]._blendMethod = prevSets[i]._blendMethod; } else { targetPortrait._timelineTrackSets[i] = new apPortrait.TimelineTrackPreset(); } } apEditorUtil.ReleaseGUIFocus(); } GUILayout.Space(5); if (targetPortrait._timelineTrackSets != null) { apPortrait.TimelineTrackPreset curTrackSet = null; for (int i = 0; i < targetPortrait._timelineTrackSets.Length; i++) { //트랙을 하나씩 적용 curTrackSet = targetPortrait._timelineTrackSets[i]; EditorGUILayout.LabelField("[" + i + "] : " + (curTrackSet._playableDirector == null ? "<None>" : curTrackSet._playableDirector.name)); PlayableDirector nextDirector = EditorGUILayout.ObjectField("Director", curTrackSet._playableDirector, typeof(PlayableDirector), true) as PlayableDirector; string nextTrackName = EditorGUILayout.DelayedTextField("Track Name", curTrackSet._trackName); int nextLayer = EditorGUILayout.DelayedIntField("Layer", curTrackSet._layer); apAnimPlayUnit.BLEND_METHOD nextBlendMethod = (apAnimPlayUnit.BLEND_METHOD)EditorGUILayout.EnumPopup("Blend", curTrackSet._blendMethod); if (nextDirector != curTrackSet._playableDirector || nextTrackName != curTrackSet._trackName || nextLayer != curTrackSet._layer || nextBlendMethod != curTrackSet._blendMethod ) { UnityEditor.SceneManagement.EditorSceneManager.MarkAllScenesDirty(); Undo.IncrementCurrentGroup(); Undo.RegisterCompleteObjectUndo(_targetPortrait, "Track Setting Changed"); curTrackSet._playableDirector = nextDirector; curTrackSet._trackName = nextTrackName; curTrackSet._layer = nextLayer; curTrackSet._blendMethod = nextBlendMethod; apEditorUtil.ReleaseGUIFocus(); } GUILayout.Space(5); } } } GUILayout.Space(20); #endif bool isChanged = false; // Control Parameters //----------------------------------------------------------------------------- if (_guiContent_Category == null) { _guiContent_Category = apGUIContentWrapper.Make("Category", false); } GUILayout.Box(_guiContent_ControlParams, _guiStyle_subTitle, GUILayout.Width(subTitleWidth), GUILayout.Height(subTitleHeight)); #if UNITY_2017_3_OR_NEWER _curControlCategory = (apControlParam.CATEGORY)EditorGUILayout.EnumFlagsField(_guiContent_Category.Content, _curControlCategory); #else _curControlCategory = (apControlParam.CATEGORY)EditorGUILayout.EnumMaskPopup(_guiContent_Category.Content, _curControlCategory); #endif EditorGUILayout.Space(); //1. 컨르롤러를 제어할 수 있도록 하자 if (_controlParams != null) { for (int i = 0; i < _controlParams.Count; i++) { if ((int)(_controlParams[i]._category & _curControlCategory) != 0) { if (GUI_ControlParam(_controlParams[i])) { isChanged = true; } } } } GUILayout.Space(30); //2. 토글 버튼을 두어서 기본 Inspector 출력 여부를 결정하자. string strBaseButton = "Show All Properties"; if (_showBaseInspector) { strBaseButton = "Hide Properties"; } if (GUILayout.Button(strBaseButton, GUILayout.Height(20))) { _showBaseInspector = !_showBaseInspector; } if (_showBaseInspector) { base.OnInspectorGUI(); } if (!Application.isPlaying && isChanged) { //플레이 중이라면 자동으로 업데이트 될 것이다. _targetPortrait.UpdateForce(); } if (_targetPortrait != null) { if (request_OpenEditor) { if (_targetPortrait._isOptimizedPortrait) { RequestDelayedOpenEditor(_targetPortrait, REQUEST_TYPE.Open); } else { RequestDelayedOpenEditor(_targetPortrait, REQUEST_TYPE.OpenAndSet); } //apEditor anyPortraitEditor = apEditor.ShowWindow(); //if (anyPortraitEditor != null && !_targetPortrait._isOptimizedPortrait) //{ // anyPortraitEditor.SetPortraitByInspector(_targetPortrait, false); //} } else if (request_QuickBake) { RequestDelayedOpenEditor(_targetPortrait, REQUEST_TYPE.QuickBake); //apEditor anyPortraitEditor = apEditor.ShowWindow(); //if (anyPortraitEditor != null) //{ // anyPortraitEditor.SetPortraitByInspector(_targetPortrait, true); // Selection.activeObject = _targetPortrait.gameObject; //} } else if (request_RefreshMeshes) { _targetPortrait.OnMeshResetInEditor(); } } } catch (Exception ex) { Debug.LogError("apInspector_Portrait Exception : " + ex); } //Profiler.EndSample(); }