private void DrawAssetPaths() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.Space(20); // GUILayout.BeginHorizontal (); { string path = AssetDatabase.GetAssetPath(currentHullPainter.paintingData); GUILayout.Label("Painting data: " + path, EditorStyles.centeredGreyMiniLabel); } // GUILayout.EndHorizontal(); // GUILayout.BeginHorizontal (); { string path = AssetDatabase.GetAssetPath(currentHullPainter.hullData); GUILayout.Label("Hull data: " + path, EditorStyles.centeredGreyMiniLabel); } // GUILayout.EndHorizontal(); if (GUILayout.Button("Disconnect from assets")) { sceneManipulator.DisconnectAssets(); currentHullPainter = null; repaintSceneView = true; regenerateOverlay = true; } }
private void DrawHullWarnings(HullPainter currentHullPainter) { List <string> warnings = new List <string> (); for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++) { Hull hull = currentHullPainter.paintingData.hulls[i]; if (hull.hasColliderError) { warnings.Add("'" + hull.name + "' generates a collider with " + hull.numColliderFaces + " faces"); } } if (warnings.Count > 0) { areErrorsFoldedOut = EditorGUILayout.Foldout(areErrorsFoldedOut, new GUIContent("Warnings", errorIcon), foldoutStyle); if (areErrorsFoldedOut) { foreach (string str in warnings) { GUILayout.Label(str); } GUILayout.Label("Unity only allows max 256 faces per hull"); GUILayout.Space(10); GUILayout.Label("Inflation has been enabled to further simplify this hull,"); GUILayout.Label("adjust the inflation amount to refine this further."); } DrawUiDivider(); } }
void OnGUI() { // Only sync on layout so ui gets same calls if (Event.current.type == EventType.Layout) { sceneManipulator.Sync(); } CreateStyles(); repaintSceneView = false; regenerateOverlay = false; hullToDelete = -1; HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null && currentHullPainter.paintingData != null) { DrawActiveGui(currentHullPainter); } else { DrawInactiveGui(); } }
private void DeleteColliders() { Undo.SetCurrentGroupName("Destroy Colliders"); HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); currentHullPainter.RemoveAllColliders(); }
private void DeleteGenerated() { Undo.SetCurrentGroupName("Delete Generated Objects"); HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); currentHullPainter.RemoveAllGenerated(); }
private void StopPainting() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null && currentHullPainter.paintingData != null) { currentHullPainter.paintingData.activeHull = -1; } }
private void DeleteHulls() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null && currentHullPainter.hullData != null) { currentHullPainter.paintingData.RemoveAllHulls(); repaintSceneView = true; } }
public void DisconnectAssets() { if (currentHullPainter != null) { Undo.SetCurrentGroupName("Disconnect Hull Painter"); Undo.DestroyObjectImmediate(currentHullPainter); Undo.IncrementCurrentGroup(); currentHullPainter = null; } }
private static void GenerateAsset(GameObject selectedObject, Mesh srcMesh) { if (!AssetDatabase.IsValidFolder("Assets/Physics Hulls")) { AssetDatabase.CreateFolder("Assets", "Physics Hulls"); } string path = "Assets/Physics Hulls/"; // Find suitable asset names string paintAssetName, hullAssetName; CreateAssetPaths(path, selectedObject.name, out paintAssetName, out hullAssetName); // Painting asset PaintingData painting = ScriptableObject.CreateInstance <PaintingData>(); painting.sourceMesh = srcMesh; AssetDatabase.CreateAsset(painting, paintAssetName); // Mesh asset HullData hulls = ScriptableObject.CreateInstance <HullData>(); AssetDatabase.CreateAsset(hulls, hullAssetName); // Connect the painting data to the hull data painting.hullData = hulls; // Get the hull painter (or create one if it doesn't exist) HullPainter selectedPainter = selectedObject.GetComponent <HullPainter>(); if (selectedPainter == null) { selectedPainter = selectedObject.AddComponent <HullPainter>(); } // Point the painter at the asset data selectedPainter.paintingData = painting; selectedPainter.hullData = hulls; // Start with a single empty hull selectedPainter.paintingData.AddHull(HullType.ConvexHull, null, false); EditorUtility.SetDirty(painting); EditorUtility.SetDirty(hulls); // Ping the painting asset in the ui (can only ping one object at once, so do the more important one) EditorGUIUtility.PingObject(painting); EditorWindow.GetWindow(typeof(HullPainterWindow)); }
private void AddHull() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null) { Undo.RecordObject(currentHullPainter.paintingData, "Add Hull"); currentHullPainter.paintingData.AddHull(defaultType, defaultMaterial, defaultIsTrigger); EditorUtility.SetDirty(currentHullPainter.paintingData); } }
private void SetAllHullsVisible(bool visible) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null && currentHullPainter.paintingData != null) { for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++) { currentHullPainter.paintingData.hulls[i].isVisible = visible; } } regenerateOverlay = true; }
public static HullPainter FindSelectedHullPainter() { // Works for components in the scene, causes NPEs for selected prefabs in the assets dir if (Selection.transforms.Length == 1) { GameObject currentSelection = Selection.transforms[0].gameObject; HullPainter painter = currentSelection.GetComponent <HullPainter>(); if (painter != null) { return(painter); } } return(null); }
public bool Sync() { if (EditorApplication.isPlayingOrWillChangePlaymode) { // If we're in play mode then don't try and keep the overlay in sync // This also means we delete the overlay when entering playmode which stops unity getting confused about objects that shouldn't really exist InternalDestroy(); return(false); } HullPainter selectedHullPainter = SelectionUtil.FindSelectedHullPainter(); MeshFilter selectedMeshFilter = SelectionUtil.FindSelectedMeshFilter(); if (selectedHullPainter != null) { SyncParentChain(selectedHullPainter.gameObject); FindOrCreateOverlay(); FindOrCreatePickClone(); SyncPickClone(selectedMeshFilter); SyncOverlay(selectedHullPainter); } else { if (pickClone != null) { targetMeshCollider.enabled = false; } if (overlayObject != null) { overlayRenderer.enabled = false; } } bool changed = false; if (currentHullPainter != selectedHullPainter) { currentHullPainter = selectedHullPainter; changed = true; } return(changed); }
/** Gui drawn if the selected object has a vaild hull painter and initialised asset data */ private void DrawActiveGui(HullPainter currentHullPainter) { scrollPosition = GUILayout.BeginScrollView(scrollPosition); GUILayout.Space(10); DrawToolGui(); DrawHullGUI(); DrawSettingsGui(); DrawHullWarnings(currentHullPainter); DrawAssetGui(); if (currentHullPainter.paintingData.hulls.Count == 0) { GUILayout.Label("No hulls created. Add a hull to start painting."); } GUILayout.Space(16); GUILayout.EndScrollView(); // Now actually perform queued up actions if (hullToDelete != -1) { Undo.RecordObject(currentHullPainter.paintingData, "Delete Hull"); currentHullPainter.paintingData.RemoveHull(hullToDelete); EditorUtility.SetDirty(currentHullPainter.paintingData); } if (regenerateOverlay) { sceneManipulator.Sync(); // may need to explicitly resync overlay data? } if (repaintSceneView) { SceneView.RepaintAll(); } }
private void DrawDefaultMaterial(float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.BeginHorizontal(); { GUILayout.Label("Default material:", GUILayout.Width(collumnWidths[0])); defaultMaterial = (PhysicMaterial)EditorGUILayout.ObjectField(defaultMaterial, typeof(PhysicMaterial), false, GUILayout.Width(collumnWidths[1] + 4)); if (GUILayout.Button("Apply To All", GUILayout.Width(collumnWidths[2]))) { currentHullPainter.SetAllMaterials(defaultMaterial); } } GUILayout.EndHorizontal(); }
private void DrawHullGUILine(int hullIndex, Hull hull, float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); Undo.RecordObject(currentHullPainter.paintingData, "Edit Hull"); GUILayout.BeginHorizontal(); { hull.name = EditorGUILayout.TextField(hull.name, GUILayout.MinWidth(60), GUILayout.Width(collumnWidths[0])); Color prevColour = hull.colour; hull.colour = EditorGUILayout.ColorField("", hull.colour, GUILayout.Width(collumnWidths[1])); if (prevColour != hull.colour) { regenerateOverlay = true; repaintSceneView = true; } hull.type = (HullType)EditorGUILayout.EnumPopup(hull.type, GUILayout.Width(collumnWidths[2])); hull.material = (PhysicMaterial)EditorGUILayout.ObjectField(hull.material, typeof(PhysicMaterial), false, GUILayout.Width(collumnWidths[3])); if (GUILayout.Button(hull.isTrigger ? triggerOnIcon : triggerOffIcon, GUILayout.Width(collumnWidths[4]))) { hull.isTrigger = !hull.isTrigger; } int prevHullIndex = currentHullPainter.paintingData.activeHull; bool isPainting = (currentHullPainter.paintingData.activeHull == hullIndex); int nowSelected = GUILayout.Toolbar(isPainting ? 0 : -1, new Texture[] { isPainting?paintOnIcon: paintOffIcon }, UnityEditor.EditorStyles.miniButton, GUILayout.Width(collumnWidths[5])); if (nowSelected == 0 && prevHullIndex != hullIndex) { // Now painting this index! currentHullPainter.paintingData.activeHull = hullIndex; } if (GUILayout.Button(deleteIcon, GUILayout.Width(collumnWidths[6]))) { hullToDelete = hullIndex; regenerateOverlay = true; repaintSceneView = true; } } GUILayout.EndHorizontal(); }
private void DrawDefaultType(float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.BeginHorizontal(); { GUILayout.Label("Default type:", GUILayout.Width(collumnWidths[0])); defaultType = (HullType)EditorGUILayout.EnumPopup(defaultType, GUILayout.Width(100)); GUILayout.Label("", GUILayout.Width(collumnWidths[1] - 100)); if (GUILayout.Button("Apply To All", GUILayout.Width(collumnWidths[2]))) { currentHullPainter.SetAllTypes(defaultType); } } GUILayout.EndHorizontal(); }
public override void OnInspectorGUI() { if (technieIcon == null) { string installPath = HullPainterWindow.FindInstallPath(); technieIcon = AssetDatabase.LoadAssetAtPath <Texture>(installPath + "TechnieIcon.png"); } if (HullPainterWindow.IsOpen()) { HullPainterWindow window = HullPainterWindow.instance; window.OnInspectorGUI(); } HullPainter selectedPainter = SelectionUtil.FindSelectedHullPainter(); if (selectedPainter != null) { if (selectedPainter.paintingData != null && selectedPainter.hullData != null) { if (GUILayout.Button(new GUIContent("Open Hull Painter", technieIcon))) { EditorWindow.GetWindow(typeof(HullPainterWindow)); } } else { MeshFilter srcMeshFilter = selectedPainter.gameObject.GetComponent <MeshFilter>(); Mesh srcMesh = srcMeshFilter != null ? srcMeshFilter.sharedMesh : null; if (srcMesh != null) { CommonUi.DrawGenerateOrReconnectGui(selectedPainter.gameObject, srcMesh); } else { GUILayout.Label("No mesh on current object!"); } } } }
private bool AreAllHullsVisible() { bool allVisible = true; HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter != null && currentHullPainter.paintingData != null) { for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++) { if (!currentHullPainter.paintingData.hulls[i].isVisible) { allVisible = false; break; } } } return(allVisible); }
public static void Reconnect(GameObject selectedObject, PaintingData newPaintingData) { Debug.Log("Reconnect " + selectedObject.name + " to " + newPaintingData.name); // Get the hull painter (or create one if it doesn't exist) HullPainter hullPainter = selectedObject.GetComponent <HullPainter>(); if (hullPainter == null) { hullPainter = selectedObject.AddComponent <HullPainter>(); } // Point the hull painter at the assets hullPainter.paintingData = newPaintingData; hullPainter.hullData = newPaintingData.hullData; EditorWindow.GetWindow(typeof(HullPainterWindow)).Repaint(); }
public bool Sync() { HullPainter selectedHullPainter = SelectionUtil.FindSelectedHullPainter(); MeshFilter selectedMeshFilter = SelectionUtil.FindSelectedMeshFilter(); if (selectedHullPainter != null) { SyncParentChain(selectedHullPainter.gameObject); FindOrCreateOverlay(); FindOrCreatePickClone(); SyncPickClone(selectedMeshFilter); SyncOverlay(selectedHullPainter); } else { if (pickClone != null) { targetMeshCollider.enabled = false; } if (overlayObject != null) { overlayRenderer.enabled = false; } } bool changed = false; if (currentHullPainter != selectedHullPainter) { currentHullPainter = selectedHullPainter; changed = true; } return(changed); }
private void DrawHullWarnings(HullPainter currentHullPainter) { List <string> warnings = new List <string> (); for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++) { Hull hull = currentHullPainter.paintingData.hulls[i]; if (hull.hasColliderError) { warnings.Add("'" + hull.name + "' generates a collider with " + hull.numColliderFaces + " faces"); } } if (warnings.Count > 0) { GUILayout.BeginHorizontal(); GUIStyle iconStyle = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter }; GUILayout.Label(errorIcon, iconStyle, GUILayout.Height(40), GUILayout.ExpandWidth(true)); GUILayout.BeginVertical(); { GUILayout.Label("Errors", EditorStyles.boldLabel); foreach (string str in warnings) { GUILayout.Label(str); } GUILayout.Label("Unity only allows max 256 faces per hull"); GUILayout.Label("Simplify this hull or split into multiple hulls"); } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } }
private void DrawDefaultAsChild(float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.BeginHorizontal(); { GUILayout.Label("Default as child:", GUILayout.Width(collumnWidths[0])); if (GUILayout.Button(defaultIsChild ? isChildIcon: nonChildIcon, GUILayout.Width(100))) { defaultIsChild = !defaultIsChild; } GUILayout.Label("", GUILayout.Width(collumnWidths[1] - 100)); if (GUILayout.Button("Apply To All", GUILayout.Width(collumnWidths[2]))) { currentHullPainter.SetAllAsChild(defaultIsChild); } } GUILayout.EndHorizontal(); }
private void DrawDefaultTrigger(float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.BeginHorizontal(); { GUILayout.Label("Default trigger:", GUILayout.Width(collumnWidths[0])); if (GUILayout.Button(defaultIsTrigger ? triggerOnIcon : triggerOffIcon, GUILayout.Width(100))) { defaultIsTrigger = !defaultIsTrigger; } GUILayout.Label("", GUILayout.Width(collumnWidths[1] - 100)); if (GUILayout.Button("Apply To All", GUILayout.Width(collumnWidths[2]))) { currentHullPainter.SetAllAsTrigger(defaultIsTrigger); } } GUILayout.EndHorizontal(); }
private void DrawFaceDepth(float[] collumnWidths) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); GUILayout.BeginHorizontal(); { GUILayout.Label("Face thickness:", GUILayout.Width(collumnWidths[0])); currentHullPainter.paintingData.faceThickness = EditorGUILayout.FloatField(currentHullPainter.paintingData.faceThickness, GUILayout.Width(collumnWidths[1] + 4)); float inc = 0.1f; if (GUILayout.Button("+")) { currentHullPainter.paintingData.faceThickness = currentHullPainter.paintingData.faceThickness + inc; } if (GUILayout.Button("-")) { currentHullPainter.paintingData.faceThickness = currentHullPainter.paintingData.faceThickness - inc; } } GUILayout.EndHorizontal(); }
private void DrawAssetGui() { areAssetsFoldedOut = EditorGUILayout.Foldout(areAssetsFoldedOut, new GUIContent("Assets", assetsIcon), foldoutStyle); if (areAssetsFoldedOut) { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); string paintingPath = AssetDatabase.GetAssetPath(currentHullPainter.paintingData); GUILayout.Label("Painting data: " + paintingPath, EditorStyles.centeredGreyMiniLabel); string hullPath = AssetDatabase.GetAssetPath(currentHullPainter.hullData); GUILayout.Label("Hull data: " + hullPath, EditorStyles.centeredGreyMiniLabel); if (GUILayout.Button("Disconnect from assets")) { sceneManipulator.DisconnectAssets(); currentHullPainter = null; repaintSceneView = true; regenerateOverlay = true; } } }
public override void OnInspectorGUI() { if (HullPainterWindow.IsOpen()) { HullPainterWindow window = HullPainterWindow.instance; window.OnInspectorGUI(); } HullPainter selectedPainter = SelectionUtil.FindSelectedHullPainter(); if (selectedPainter != null) { if (selectedPainter.paintingData != null && selectedPainter.hullData != null) { if (GUILayout.Button("Open Hull Painter")) { EditorWindow.GetWindow(typeof(HullPainterWindow)); } } else { MeshFilter srcMeshFilter = selectedPainter.gameObject.GetComponent <MeshFilter>(); Mesh srcMesh = srcMeshFilter != null ? srcMeshFilter.sharedMesh : null; if (srcMesh != null) { CommonUi.DrawGenerateOrReconnectGui(selectedPainter.gameObject, srcMesh); } else { GUILayout.Label("No mesh on current object!"); } } } }
private void DrawHullGUI() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); float baseWidth = EditorGUIUtility.currentViewWidth; float fixedWidth = 45 + 80 + 50 + 40 + 50 + 32; // sum of fixed widths below, plus 30px extra for window chrome float flexibleWidth = baseWidth - fixedWidth; float[] collumnWidth = { flexibleWidth * 0.5f, 45, 80, flexibleWidth * 0.5f, 50, 40, 50 }; GUILayout.BeginHorizontal(); { GUILayout.Label("Name", GUILayout.Width(collumnWidth[0])); GUILayout.Label("Colour", GUILayout.Width(collumnWidth[1])); GUILayout.Label("Type", GUILayout.Width(collumnWidth[2])); GUILayout.Label("Material", GUILayout.Width(collumnWidth[3])); GUILayout.Label("Trigger", GUILayout.Width(collumnWidth[4])); GUILayout.Label("Paint", GUILayout.Width(collumnWidth[5])); GUILayout.Label("Delete", GUILayout.Width(collumnWidth[6])); } GUILayout.EndHorizontal(); for (int i = 0; i < currentHullPainter.paintingData.hulls.Count; i++) { DrawHullGUILine(i, currentHullPainter.paintingData.hulls[i], collumnWidth); } GUILayout.BeginHorizontal(); { // if (GUILayout.Button("Add Hull", addHullIcon, GUILayout.Width(collumnWidth[0]))) if (GUILayout.Button(new GUIContent("Add Hull", addHullIcon), GUILayout.Width(collumnWidth[0]))) { AddHull(); } GUILayout.Label("", GUILayout.Width(collumnWidth[1])); GUILayout.Label("", GUILayout.Width(collumnWidth[2])); GUILayout.Label("", GUILayout.Width(collumnWidth[3])); GUILayout.Label("", GUILayout.Width(collumnWidth[4])); if (GUILayout.Button("Stop", GUILayout.Width(collumnWidth[5]))) { StopPainting(); } if (GUILayout.Button("Del All", GUILayout.Width(collumnWidth[6]))) { DeleteHulls(); } } GUILayout.EndHorizontal(); }
/** Gui drawn if the selected object has a vaild hull painter and initialised asset data */ private void DrawActiveGui(HullPainter currentHullPainter) { scrollPosition = GUILayout.BeginScrollView(scrollPosition); GUILayout.Space(10); DrawColliderButtons(); GUILayout.Space(4); DrawHullGUI(); GUILayout.Space(20); float baseWidth = EditorGUIUtility.currentViewWidth - 20; // -32px for window chrome float fixedWidth = 120 + 120; // sum of fixed widths below float flexibleWidth = baseWidth - fixedWidth; float[] collumnWidth = { 120, flexibleWidth, 120, }; DrawDefaultType(collumnWidth); DrawDefaultMaterial(collumnWidth); DrawDefaultTrigger(collumnWidth); DrawFaceDepth(collumnWidth); DrawHullWarnings(currentHullPainter); DrawAssetPaths(); if (currentHullPainter.paintingData.hulls.Count == 0) { GUILayout.Label("No hulls created. Add a hull to start painting."); } GUILayout.Space(16); GUILayout.EndScrollView(); // Now actually perform queued up actions if (hullToDelete != -1) { Undo.RecordObject(currentHullPainter.paintingData, "Delete Hull"); currentHullPainter.paintingData.RemoveHull(hullToDelete); EditorUtility.SetDirty(currentHullPainter.paintingData); } if (regenerateOverlay) { sceneManipulator.Sync(); // may need to explicitly resync overlay data? } if (repaintSceneView) { SceneView.RepaintAll(); } }
private void GenerateColliders() { HullPainter currentHullPainter = sceneManipulator.GetCurrentHullPainter(); if (currentHullPainter == null) { return; } Undo.RegisterCompleteObjectUndo(currentHullPainter.gameObject, "Generate Colliders"); // Fetch the data assets PaintingData paintingData = currentHullPainter.paintingData; HullData hullData = currentHullPainter.hullData; string hullAssetPath = AssetDatabase.GetAssetPath(hullData); // Create / update the hull meshes foreach (Hull hull in paintingData.hulls) { paintingData.GenerateCollisionMesh(hull, sceneManipulator.GetTargetVertices(), sceneManipulator.GetTargetTriangles()); } // Sync the in-memory hull meshes with the asset meshes in hullAssetPath List <Mesh> existingMeshes = GetAllMeshesInAsset(hullAssetPath); foreach (Mesh existing in existingMeshes) { if (!paintingData.ContainsMesh(existing)) { GameObject.DestroyImmediate(existing, true); } } foreach (Hull hull in paintingData.hulls) { if (hull.collisionMesh != null) { if (!existingMeshes.Contains(hull.collisionMesh)) { AssetDatabase.AddObjectToAsset(hull.collisionMesh, hullAssetPath); } } if (hull.faceCollisionMesh != null) { if (existingMeshes.Contains(hull.faceCollisionMesh)) { AssetDatabase.AddObjectToAsset(hull.faceCollisionMesh, hullAssetPath); } } } EditorUtility.SetDirty(hullData); AssetDatabase.SaveAssets(); // Add collider components to the target object currentHullPainter.CreateColliderComponents(); }