/////////////////////////////////////////////////// ////////// 버텍스 에딧모드 ///////////////// /////////////////////////////////////////////////// void VertEditMode(MotionPath Ge, PathInfoData GetPathInfo) { //선택한 버텍스용 스타일 GUIStyle Style = new GUIStyle(); Style.contentOffset = new Vector2(-7, -9); //아이콘 위치 조정 //수정 모드 했을 때 버튼 크기 float ButtonSize = 15; float ButtonPosAdd = -ButtonSize / 2; //패스 그리기 for (int j = 0; j < GetPathInfo.VertexPos.Length; j++) { if (j != GetPathInfo.EditVertIdx) { Handles.BeginGUI(); GUI.backgroundColor = new Color(2, 2, 2); if (GUI.Button(new Rect(HandleUtility.WorldToGUIPoint(GetPathInfo.VertexPos[j]).x + ButtonPosAdd, HandleUtility.WorldToGUIPoint(GetPathInfo.VertexPos[j]).y + ButtonPosAdd, ButtonSize, ButtonSize), "")) { GetPathInfo.EditVertIdx = j; //Genarator.MovePosition.Insert(i, new Vector3(Genarator.MovePosition[i].x, Genarator.MovePosition[i].y, Genarator.MovePosition[i].z)); } GUI.backgroundColor = GUI.color; Handles.EndGUI(); } //현재 선택중인 버텍스 else { Handles.Label(GetPathInfo.VertexPos[j], EditorGUIUtility.IconContent("d_winbtn_mac_min"), Style); } } //위치 기즈모 if (GetPathInfo.VertexPos.Length > GetPathInfo.EditVertIdx) { Undo.RecordObject(Ge, "SaveHandlePos"); EditorGUI.BeginChangeCheck(); GetPathInfo.VertexPos[GetPathInfo.EditVertIdx] = Handles.PositionHandle(GetPathInfo.VertexPos[GetPathInfo.EditVertIdx], Quaternion.identity); if (EditorGUI.EndChangeCheck()) { Ge.GenerateMesh(Ge.PathInfo.Count, Ge.CreateMeshInfo.Count_Y, Ge.PathInfo[0].VertexPos.Length); } } }
public override void OnInspectorGUI() { base.OnInspectorGUI(); //EditorGUILayout.LabelField("", GUI.skin.horizontalSlider); //GUILayout.Space(100); MotionPath Ge = (MotionPath)target; //All Undo Undo.RecordObject(Ge, "All State"); //애니메이터 EditorGUI.BeginChangeCheck(); Ge.Animator = (Animator)EditorGUILayout.ObjectField("Animator", Ge.Animator, typeof(Animator)); bool ChangeAniamtor = EditorGUI.EndChangeCheck(); //애니메이터 바뀜 // //오브젝트 // for (int i = 0; i < Ge.PathInfo.Count; i++) // { // EditorGUI.BeginChangeCheck(); // Ge.PathInfo[i].TargetObject = (GameObject)EditorGUILayout.ObjectField("Target " + "(" + "Path " + (i + 1).ToString() + ")", Ge.PathInfo[i].TargetObject, typeof(GameObject)); // if (EditorGUI.EndChangeCheck()) // { // if (Ge.PathInfo[i].TargetObject != null) // { // //추적 오브젝트 변경 시 패스 재생성 // if (Ge.PathInfo[i].AutoUpdate) // { // CreatePath(Ge.PathInfo[i]); // } // } // } // } /////////////////////////////////////////////////////// ////////////////// GUI /////////////////////// /////////////////////////////////////////////////////// GUILayout.Space(10); //애니메이터가 있을 때 if (Ge.Animator != null) { //Ge.SelectToolbar = GUILayout.Toolbar(Ge.SelectToolbar, Ge.ToolbarName, GUILayout.MinHeight(35)); GUILayout.BeginHorizontal(); if (GUILayout.Button("Add Path")) { Ge.PathInfo.Add(new MotionPath.PathInfoData()); } //패스가 2개 초과일 경우 if (Ge.PathInfo.Count > 2) { GUI.backgroundColor = Color.red * 1.5f; if (GUILayout.Button("Remove Path" + " (" + (Ge.SelectPath + 1).ToString() + ")", GUILayout.MaxWidth(130))) { Ge.PathInfo.RemoveAt(Ge.SelectPath); Ge.SelectPath = Mathf.Min(Ge.PathInfo.Count - 1, Ge.SelectPath); //지운게 마지막꺼면 SceneView.RepaintAll(); Ge.GenerateMesh(Ge.PathInfo.Count, Ge.CreateMeshInfo.Count_Y, Ge.PathInfo[0].VertexPos.Length); } GUI.backgroundColor = GUI.color; } GUILayout.EndHorizontal(); ////////////////////////////////////////// ////////// 버튼 리스트 /////////// ////////////////////////////////////////// EditorGUI.BeginChangeCheck(); GUILayout.BeginHorizontal(); //Animation버튼 GUI.backgroundColor = Ge.SelectToolbar == 0 ? new Color(2, 1, 0) : GUI.color; if (GUILayout.Button("Animation", GUILayout.MinHeight(35))) { Ge.SelectToolbar = 0; } GUI.backgroundColor = GUI.color; //Path 버튼 for (int i = 0; i < Ge.PathInfo.Count; i++) { //Path 버튼 선택 했을 때 색 GUI.backgroundColor = Ge.SelectToolbar == 1 && Ge.SelectPath == i ? new Color(2, 1, 0) : GUI.color; if (GUILayout.Button("Path " + (i + 1).ToString() + " (" + Ge.PathInfo[i].VertexPos.Length.ToString() + ")", GUILayout.MinHeight(35))) { Ge.SelectToolbar = 1; Ge.SelectPath = i; } GUI.backgroundColor = GUI.color; } //메쉬 버튼 GUI.backgroundColor = Ge.SelectToolbar == 2 ? new Color(2, 1, 0) : GUI.color; if (GUILayout.Button("Mesh", GUILayout.MinHeight(35))) { Ge.SelectToolbar = 2; } GUI.backgroundColor = GUI.color; //가로 나열 마무리 GUILayout.EndHorizontal(); //버튼들 누르면 패스 표시 정보 업데이트를 위한 씬 다시 로드 bool ClickToolbar = EditorGUI.EndChangeCheck(); if (ClickToolbar) { SceneView.RepaintAll(); //패스 버튼 누르면 씬 정보 다시 그리기 } //버튼 선택에 따른 인스펙터 드로우 if (Ge.SelectToolbar == 0) { //애니메이션정보 GUI GUILayout.BeginVertical("GroupBox"); DrawAniInfo(); GUILayout.EndVertical(); } //패스 if (Ge.SelectToolbar == 1) { //패스가 그릴 오브젝트 EditorGUI.BeginChangeCheck(); GUILayout.Space(10); Ge.PathInfo[Ge.SelectPath].TargetObject = (GameObject)EditorGUILayout.ObjectField("Path Target", Ge.PathInfo[Ge.SelectPath].TargetObject, typeof(GameObject)); if (EditorGUI.EndChangeCheck()) { if (Ge.PathInfo[Ge.SelectPath].TargetObject != null) { //추적 오브젝트 변경 시 패스 재생성 if (Ge.PathInfo[Ge.SelectPath].AutoUpdate) { CreatePath(Ge.PathInfo[Ge.SelectPath]); } } } //패스가 2개 초과일 경우 // if (Ge.PathInfo.Count > 2) // { // GUI.backgroundColor = Color.red * 1.5f; // if (GUILayout.Button("Remove Path")) // { // Ge.PathInfo.RemoveAt(Ge.SelectPath); // Ge.SelectPath = Mathf.Min(Ge.PathInfo.Count - 1, Ge.SelectPath); //지운게 마지막꺼면 // SceneView.RepaintAll(); // Ge.GenerateMesh(Ge.PathInfo.Count, Ge.CreateMeshInfo.Count_Y, Ge.PathInfo[0].VertexPos.Length); // } // GUI.backgroundColor = GUI.color; // } //오브젝트 있을 때 if (Ge.PathInfo[Ge.SelectPath].TargetObject != null) { //패스 GUI GUILayout.BeginVertical("GroupBox"); DrawPathInfo(Ge.PathInfo[Ge.SelectPath]); GUILayout.EndVertical(); //패스 To 버텍스위치 GUI GUILayout.BeginVertical("GroupBox"); Viewer_VertexPos(Ge.PathInfo[Ge.SelectPath]); GUILayout.EndVertical(); } } //메쉬 생성 else if (Ge.SelectToolbar == 2) { GUILayout.BeginVertical("GroupBox"); GenerateMeshViewer(Ge); GUILayout.EndVertical(); } } // //패스 리스트들 그리기 // void DrawSelectPath_Inspector() // { // //패스 GUI // GUILayout.BeginVertical("GroupBox"); // DrawPathInfo(Ge.PathInfo[Ge.SelectPath]); // GUILayout.EndVertical(); // //패스 To 버텍스위치 GUI // GUILayout.BeginVertical("GroupBox"); // Viewer_VertexPos(Ge.PathInfo[Ge.SelectPath]); // GUILayout.EndVertical(); // } //패스 정보 void DrawPathInfo(MotionPath.PathInfoData GetPathInfo) { PathViewerSetting(GetPathInfo); GetPathInfo.AutoUpdate = EditorGUILayout.Toggle("Auto Update", GetPathInfo.AutoUpdate); EditorGUI.BeginChangeCheck(); int PathDetail = EditorGUILayout.IntSlider("PathDetail (Frame)", GetPathInfo.PathFrame, 1, 500); PathDetail = Mathf.Max(PathDetail, 1); //최소값 GetPathInfo.PathFrame = PathDetail; if (EditorGUI.EndChangeCheck()) //패스 디테일 수정하면 업데이트 { if (GetPathInfo.AutoUpdate) { CreatePath(GetPathInfo); } } if (!GetPathInfo.AutoUpdate) { if (GUILayout.Button("Create Path")) { CreatePath(GetPathInfo); } } } //CreatePath (패스 생성) void CreatePath(MotionPath.PathInfoData GetPathInfo) { if (GetPathInfo.TargetObject != null) { float FirstFrame = Ge.AnimationSlider; //현재 포즈 시간 백업 List <Vector3> NewPathPosition = new List <Vector3>(2); for (float i = Ge.StartFrame; i < Ge.EndFrame; i += (1f / (float)GetPathInfo.PathFrame)) { Ge.AnimationSlider = i; //포즈 시간 업데이트 UpDatePos(); //포즈 업데이트 NewPathPosition.Add(GetPathInfo.TargetObject.transform.position); } GetPathInfo.PathPos = NewPathPosition.ToArray(); Ge.AnimationSlider = FirstFrame; //처음 설정한 포즈 시간으로 백업 UpDatePos(); //포즈 업데이트 //버텍스 평균 위치값 자동 업데이트 if (GetPathInfo.Vertex_AutoUpdate) { CountVertexPos(GetPathInfo); //버텍스 평균 위치값 업데이트 } } } //패스 보기 설정 void PathViewerSetting(MotionPath.PathInfoData GetPathInfo) { GetPathInfo.PathViewerSetting = EditorGUILayout.Toggle("Path View Setting", GetPathInfo.PathViewerSetting); if (GetPathInfo.PathViewerSetting) { GUILayout.BeginVertical("GroupBox"); EditorGUI.BeginChangeCheck(); GetPathInfo.PathColor = EditorGUILayout.ColorField("Path Color", GetPathInfo.PathColor); GetPathInfo.PathWidth = EditorGUILayout.FloatField("Path Width", GetPathInfo.PathWidth); if (EditorGUI.EndChangeCheck()) { if (GetPathInfo.AutoUpdate) { CreatePath(GetPathInfo); } } GUILayout.EndVertical(); } } //애니메이션 정보 void DrawAniInfo() { //애니메이터 바뀜 if (ChangeAniamtor) { Ge.AnimationClips = Ge.Animator.runtimeAnimatorController.animationClips; Ge.AniClipsName = new string[Ge.AnimationClips.Length]; for (int i = 0; i < Ge.AniClipsName.Length; i++) { Ge.AniClipsName[i] = Ge.AnimationClips[i].name; } } float SelectClipLength = Ge.AnimationClips[Ge.SelectAniClip].length; //선택한 클립의 최대 길이 //플레이할 애니메이션 선택 EditorGUI.BeginChangeCheck(); Ge.SelectAniClip = EditorGUILayout.Popup("재생할 애니메이션", Ge.SelectAniClip, Ge.AniClipsName); if (EditorGUI.EndChangeCheck()) { Debug.Log("애니 변경"); Ge.PlayStateName = GetStringFromAniClip(Ge.Animator, Ge.AnimationClips[Ge.SelectAniClip]); //재생할 애니메이션 스테이트 이름 가져오기 //시작, 끝 프레임 기본 설정 //Ge.StartFrame = 0; //Ge.EndFrame = Ge.AnimationClips[Ge.SelectAniClip].length; UpDatePos(); for (int i = 0; i < Ge.PathInfo.Count; i++) { if (Ge.PathInfo[i].AutoUpdate) { CreatePath(Ge.PathInfo[i]); } } } EditorGUI.BeginChangeCheck(); //포즈 관련 변수 업데이트 되는지 확인 //GUILayout.BeginHorizontal(); //최소값 float SetStartFrame = EditorGUILayout.FloatField("Start Frame", Ge.StartFrame); SetStartFrame = Mathf.Clamp(SetStartFrame, 0, Ge.EndFrame); Ge.StartFrame = SetStartFrame; //최대값 float SetEndFrame = EditorGUILayout.FloatField("End Frame", Ge.EndFrame); SetEndFrame = Mathf.Clamp(SetEndFrame, Ge.StartFrame, SelectClipLength); Ge.EndFrame = SetEndFrame; //GUILayout.EndHorizontal(); EditorGUILayout.MinMaxSlider("Set Frame", ref Ge.StartFrame, ref Ge.EndFrame, 0, SelectClipLength); bool ChangeMinMax = EditorGUI.EndChangeCheck(); if (ChangeMinMax) //패스랑 관련된 값들 변경되면 패스 새로 생성 { for (int i = 0; i < Ge.PathInfo.Count; i++) { if (Ge.PathInfo[i].AutoUpdate) { CreatePath(Ge.PathInfo[i]); } } } //애니 재생 EditorGUI.BeginChangeCheck(); //포즈 관련 변수 업데이트 되는지 확인 Ge.AnimationSlider = EditorGUILayout.Slider("Ani Play", Ge.AnimationSlider, Ge.StartFrame, Ge.EndFrame); //포즈 관련된 변수들이 변했을 경우 if (EditorGUI.EndChangeCheck() || ChangeMinMax) { UpDatePos(); //애니메이션 포즈 업데이트 } } //캐릭터 애니메이션 업데이트 void UpDatePos() { Ge.Animator.Play(Ge.PlayStateName, -1, Ge.AnimationSlider); Ge.Animator.Update(Ge.AnimationSlider - 1); } }
/////////////////////////////////////////////////////////////////// ///////////////////// MeshViewer /////////////////////// /////////////////////////////////////////////////////////////////// void GenerateMeshViewer(MotionPath Ge) { bool SameVert = Ge.IsSamePathVert(); GUIStyle Font = new GUIStyle(); Font.normal.textColor = Color.green; Font.alignment = TextAnchor.MiddleCenter; Font.fontStyle = FontStyle.Bold; Font.fontSize = 18; if (!SameVert) { GUILayout.Label("Path의 모든 버텍스 갯수가 동일 해야 합니다", Font); } else { GUI.backgroundColor = new Color(0.75f, 0.75f, 0.75f); GUILayout.BeginVertical("GroupBox"); GUILayout.Label(Ge.MeshFilter.mesh.vertices.Length.ToString() + " Verts, " + (Ge.MeshFilter.mesh.triangles.Length / 3).ToString() + " tris", Font); GUILayout.EndVertical(); GUI.backgroundColor = GUI.color; EditorGUI.BeginChangeCheck(); Ge.Debug_VertInfo = EditorGUILayout.Toggle("View VertIdx", Ge.Debug_VertInfo); if (Ge.Debug_VertInfo) { Ge.Debug_VertPos = EditorGUILayout.Toggle("View VertPos", Ge.Debug_VertPos); } Ge.Debug_DrawTriLine = EditorGUILayout.Toggle("View Tris", Ge.Debug_DrawTriLine); if (EditorGUI.EndChangeCheck()) { SceneView.RepaintAll(); } EditorGUI.BeginChangeCheck(); Ge.CreateMeshInfo.Count_Y = EditorGUILayout.IntSlider("Count_Y", Ge.CreateMeshInfo.Count_Y, 1, 10); if (GUILayout.Button("InvertUV_X")) { Ge.CreateMeshInfo.InvertUV_X = !Ge.CreateMeshInfo.InvertUV_X; } if (GUILayout.Button("InvertUV_Y")) { Ge.CreateMeshInfo.InvertUV_Y = !Ge.CreateMeshInfo.InvertUV_Y; } if (GUILayout.Button("FlipFace")) { Ge.CreateMeshInfo.FlipFace = !Ge.CreateMeshInfo.FlipFace; } bool ChangeMeshData = EditorGUI.EndChangeCheck(); if (ChangeMeshData) //메쉬 관련 데이터 변경 시 메쉬 다시 구성 { Ge.GenerateMesh(Ge.PathInfo.Count, Ge.CreateMeshInfo.Count_Y, Ge.PathInfo[0].VertexPos.Length); } if (GUILayout.Button("GenerateMesh (메쉬 생성)")) { Ge.GenerateMesh(Ge.PathInfo.Count, Ge.CreateMeshInfo.Count_Y, Ge.PathInfo[0].VertexPos.Length); } EditorGUI.BeginDisabledGroup(Ge.MeshFilter.mesh.vertices.Length == 0); //버튼 비활성화 조건 { if (GUILayout.Button("Save Mesh")) { Ge.SaveMesh(Ge.MeshFilter.mesh); } } EditorGUI.EndDisabledGroup(); } }