public static LakePolygon CreatePolygon(Material material, List <Vector3> positions = null) { GameObject gameobject = new GameObject("Lake Polygon"); LakePolygon polygon = gameobject.AddComponent <LakePolygon>(); MeshRenderer meshRenderer = gameobject.AddComponent <MeshRenderer>(); meshRenderer.receiveShadows = false; meshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off; if (material != null) { meshRenderer.sharedMaterial = material; } if (positions != null) { for (int i = 0; i < positions.Count; i++) { polygon.AddPoint(positions[i]); } } return(polygon); }
protected virtual void OnSceneGUI() { if (lakePolygon == null) { lakePolygon = (LakePolygon)target; } Color baseColor = Handles.color; int controlId = GUIUtility.GetControlID(FocusType.Passive); if (lakePolygon != null) { if (lakePolygon.lockHeight) { for (int i = 1; i < lakePolygon.points.Count; i++) { Vector3 vec = lakePolygon.points[i]; vec.y = lakePolygon.points[0].y; lakePolygon.points[i] = vec; } } } { Vector3[] points = new Vector3[lakePolygon.splinePoints.Count]; for (int i = 0; i < lakePolygon.splinePoints.Count; i++) { points[i] = lakePolygon.splinePoints[i] + lakePolygon.transform.position; } Handles.color = Color.white; Handles.DrawPolyLine(points); if (Event.current.commandName == "UndoRedoPerformed") { lakePolygon.GeneratePolygon(); return; } if (selectedPosition >= 0 && selectedPosition < lakePolygon.points.Count) { Handles.color = Color.red; Handles.SphereHandleCap(0, (Vector3)lakePolygon.points[selectedPosition] + lakePolygon.transform.position, Quaternion.identity, 1, EventType.Repaint); } int controlPointToDelete = -1; for (int j = 0; j < lakePolygon.points.Count; j++) { EditorGUI.BeginChangeCheck(); Vector3 handlePos = (Vector3)lakePolygon.points[j] + lakePolygon.transform.position; GUIStyle style = new GUIStyle(); style.normal.textColor = Color.red; Vector3 screenPoint = Camera.current.WorldToScreenPoint(handlePos); if (screenPoint.z > 0) { Handles.Label(handlePos + Vector3.up * HandleUtility.GetHandleSize(handlePos), "Point: " + j.ToString(), style); } if (Event.current.control && Event.current.shift) { int id = GUIUtility.GetControlID(FocusType.Passive); if (HandleUtility.nearestControl == id) { Handles.color = Color.white; if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { controlPointToDelete = j; } } else { Handles.color = Handles.xAxisColor; } float size = 0.6f; size = HandleUtility.GetHandleSize(handlePos) * size; if (Event.current.type == EventType.Repaint) { Handles.SphereHandleCap(id, (Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Repaint); } else if (Event.current.type == EventType.Layout) { Handles.SphereHandleCap(id, (Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Quaternion.identity, size, EventType.Layout); } } else if (Tools.current == Tool.Move) { float size = 0.6f; size = HandleUtility.GetHandleSize(handlePos) * size; Handles.color = Handles.xAxisColor; Vector3 pos = Handles.Slider((Vector3)lakePolygon.points[j] + lakePolygon.transform.position, Vector3.right, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position; if (!lakePolygon.lockHeight) { Handles.color = Handles.yAxisColor; pos = Handles.Slider((Vector3)pos + lakePolygon.transform.position, Vector3.up, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position; } Handles.color = Handles.zAxisColor; pos = Handles.Slider((Vector3)pos + lakePolygon.transform.position, Vector3.forward, size, Handles.ArrowHandleCap, 0.01f) - lakePolygon.transform.position; Vector3 halfPos = (Vector3.right + Vector3.forward) * size * 0.3f; Handles.color = Handles.yAxisColor; pos = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.up, Vector3.right, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos; halfPos = (Vector3.right + Vector3.up) * size * 0.3f; if (!lakePolygon.lockHeight) { Handles.color = Handles.zAxisColor; pos = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.forward, Vector3.right, Vector3.up, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos; halfPos = (Vector3.up + Vector3.forward) * size * 0.3f; Handles.color = Handles.xAxisColor; pos = Handles.Slider2D((Vector3)pos + lakePolygon.transform.position + halfPos, Vector3.right, Vector3.up, Vector3.forward, size * 0.3f, Handles.RectangleHandleCap, 0.01f) - lakePolygon.transform.position - halfPos; } lakePolygon.points[j] = pos; } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Change Position"); lakePolygon.GeneratePolygon(); #if VEGETATION_STUDIO RegenerateVegetationMask(); #endif #if VEGETATION_STUDIO_PRO RegenerateBiomMask(); #endif } } if (controlPointToDelete >= 0) { Undo.RecordObject(lakePolygon, "Remove point"); Undo.RecordObject(lakePolygon.transform, "Remove point"); lakePolygon.RemovePoint(controlPointToDelete); lakePolygon.GeneratePolygon(); GUIUtility.hotControl = controlId; Event.current.Use(); HandleUtility.Repaint(); controlPointToDelete = -1; } if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.control) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { Undo.RecordObject(lakePolygon, "Add point"); Undo.RecordObject(lakePolygon.transform, "Add point"); Vector3 position = hit.point - lakePolygon.transform.position; lakePolygon.AddPoint(position); lakePolygon.GeneratePolygon(); #if VEGETATION_STUDIO RegenerateVegetationMask(); #endif #if VEGETATION_STUDIO_PRO RegenerateBiomMask(); #endif GUIUtility.hotControl = controlId; Event.current.Use(); HandleUtility.Repaint(); } } if (!Event.current.control && Event.current.shift) { Ray ray = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); RaycastHit hit; if (Physics.Raycast(ray, out hit)) { int idMin = -1; float distanceMin = float.MaxValue; for (int j = 0; j < lakePolygon.points.Count; j++) { Vector3 handlePos = (Vector3)lakePolygon.points[j] + lakePolygon.transform.position; float pointDist = Vector3.Distance(hit.point, handlePos); if (pointDist < distanceMin) { distanceMin = pointDist; idMin = j; } } Vector3 posOne = (Vector3)lakePolygon.points[idMin] + lakePolygon.transform.position; Vector3 posTwo; Vector3 posPrev = (Vector3)lakePolygon.points[lakePolygon.ClampListPos(idMin - 1)] + lakePolygon.transform.position; Vector3 posNext = (Vector3)lakePolygon.points[lakePolygon.ClampListPos(idMin + 1)] + lakePolygon.transform.position; if (Vector3.Distance(hit.point, posPrev) > Vector3.Distance(hit.point, posNext)) { posTwo = posNext; } else { posTwo = posPrev; idMin = lakePolygon.ClampListPos(idMin - 1); } Handles.color = Handles.xAxisColor; Handles.DrawLine(hit.point, posOne); Handles.DrawLine(hit.point, posTwo); if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { Undo.RecordObject(lakePolygon, "Add point"); Undo.RecordObject(lakePolygon.transform, "Add point"); Vector4 position = hit.point - lakePolygon.transform.position; lakePolygon.AddPointAfter(idMin); lakePolygon.ChangePointPosition(idMin + 1, position); lakePolygon.GeneratePolygon(); GUIUtility.hotControl = controlId; Event.current.Use(); HandleUtility.Repaint(); } } } if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.control) { GUIUtility.hotControl = 0; } if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && Event.current.shift) { GUIUtility.hotControl = 0; } } }
public override void OnInspectorGUI() { if (lakePolygon == null) { lakePolygon = (LakePolygon)target; } EditorGUILayout.Space(); EditorGUILayout.HelpBox("Add Point - CTRL + Left Mouse Button Click \n" + "Add point between existing points - SHIFT + Left Button Click \n" + "Remove point - CTRL + SHIFT + Left Button Click", MessageType.Info); EditorGUILayout.Space(); lakePolygon.currentProfile = (LakePolygonProfile)EditorGUILayout.ObjectField("Lake profile", lakePolygon.currentProfile, typeof(LakePolygonProfile), false); if (GUILayout.Button("Create profile from settings")) { LakePolygonProfile asset = ScriptableObject.CreateInstance <LakePolygonProfile>(); MeshRenderer ren = lakePolygon.GetComponent <MeshRenderer>(); asset.lakeMaterial = ren.sharedMaterial; asset.terrainCarve = lakePolygon.terrainCarve; asset.distSmooth = lakePolygon.distSmooth; asset.uvScale = lakePolygon.uvScale; asset.distSmoothStart = lakePolygon.distSmoothStart; asset.terrainPaintCarve = lakePolygon.terrainPaintCarve; asset.currentSplatMap = lakePolygon.currentSplatMap; asset.maximumTriangleSize = lakePolygon.maximumTriangleSize; asset.traingleDensity = lakePolygon.traingleDensity; string path = EditorUtility.SaveFilePanelInProject("Save new spline profile", lakePolygon.gameObject.name + ".asset", "asset", "Please enter a file name to save the spline profile to"); if (!string.IsNullOrEmpty(path)) { AssetDatabase.CreateAsset(asset, path); AssetDatabase.SaveAssets(); lakePolygon.currentProfile = asset; } } if (lakePolygon.currentProfile != null && GUILayout.Button("Save profile from settings")) { MeshRenderer ren = lakePolygon.GetComponent <MeshRenderer>(); lakePolygon.currentProfile.lakeMaterial = ren.sharedMaterial; lakePolygon.currentProfile.terrainCarve = lakePolygon.terrainCarve; lakePolygon.currentProfile.distSmooth = lakePolygon.distSmooth; lakePolygon.currentProfile.uvScale = lakePolygon.uvScale; lakePolygon.currentProfile.distSmoothStart = lakePolygon.distSmoothStart; lakePolygon.currentProfile.terrainPaintCarve = lakePolygon.terrainPaintCarve; lakePolygon.currentProfile.currentSplatMap = lakePolygon.currentSplatMap; lakePolygon.currentProfile.maximumTriangleSize = lakePolygon.maximumTriangleSize; lakePolygon.currentProfile.traingleDensity = lakePolygon.traingleDensity; AssetDatabase.SaveAssets(); } if (lakePolygon.currentProfile != null && lakePolygon.currentProfile != lakePolygon.oldProfile) { ResetToProfile(); EditorUtility.SetDirty(lakePolygon); } if (CheckProfileChange()) { EditorGUILayout.HelpBox("Profile data changed.", MessageType.Info); } if (lakePolygon.currentProfile != null && GUILayout.Button("Reset to profile")) { ResetToProfile(); } EditorGUILayout.Space(); EditorGUILayout.Space(); EditorGUI.BeginChangeCheck(); pointsFolded = EditorGUILayout.Foldout(pointsFolded, "Points:"); EditorGUI.indentLevel++; if (pointsFolded) { PointsUI(); } lakePolygon.lockHeight = EditorGUILayout.Toggle("Lock height", lakePolygon.lockHeight); EditorGUILayout.BeginHorizontal(); lakePolygon.height = EditorGUILayout.FloatField(lakePolygon.height); if (GUILayout.Button("Set heights")) { for (int i = 0; i < lakePolygon.points.Count; i++) { Vector3 point = lakePolygon.points[i]; point.y = lakePolygon.height - lakePolygon.transform.position.y; lakePolygon.points[i] = point; } lakePolygon.GeneratePolygon(); } EditorGUILayout.EndHorizontal(); lakePolygon.yOffset = EditorGUILayout.FloatField("Y offset mesh", lakePolygon.yOffset); EditorGUI.indentLevel--; EditorGUILayout.Space(); GUILayout.Label("Mesh settings:", EditorStyles.boldLabel); EditorGUI.indentLevel++; string meshResolution = "Triangles density" + "(" + lakePolygon.trianglesGenerated + " tris)"; EditorGUILayout.LabelField(meshResolution); lakePolygon.maximumTriangleSize = EditorGUILayout.FloatField("Maximum triangle size", lakePolygon.maximumTriangleSize); lakePolygon.traingleDensity = 1 / (float)EditorGUILayout.IntSlider("Spline density", (int)(1 / (float)lakePolygon.traingleDensity), 1, 100); lakePolygon.uvScale = EditorGUILayout.FloatField("UV scale", lakePolygon.uvScale); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Lake changed"); lakePolygon.GeneratePolygon(); } EditorGUI.indentLevel--; EditorGUILayout.Space(); if (GUILayout.Button("Generate polygon")) { lakePolygon.GeneratePolygon(); } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Terrain terrain = Terrain.activeTerrain; GUILayout.Label("Terrain carve:", EditorStyles.boldLabel); if (terrain != null) { EditorGUI.indentLevel++; lakePolygon.terrainCarve = EditorGUILayout.CurveField("Terrain carve", lakePolygon.terrainCarve); lakePolygon.distSmooth = EditorGUILayout.FloatField("Smooth distance", lakePolygon.distSmooth); lakePolygon.distSmoothStart = EditorGUILayout.FloatField("Smooth start distance", lakePolygon.distSmoothStart); EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Lake curve changed"); } if (GUILayout.Button("Carve Terrain")) { TerrainCarve(); } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); EditorGUI.indentLevel++; lakePolygon.terrainPaintCarve = EditorGUILayout.CurveField("Terrain paint", lakePolygon.terrainPaintCarve); int splatNumber = terrain.terrainData.splatPrototypes.Length; if (splatNumber > 0) { string[] options = new string[splatNumber]; for (int i = 0; i < splatNumber; i++) { options[i] = i + " - "; if (terrain.terrainData.splatPrototypes[i].texture != null) { options[i] += terrain.terrainData.splatPrototypes[i].texture.name; } } EditorGUILayout.BeginHorizontal(); GUILayout.Label(" Splat id:"); lakePolygon.currentSplatMap = EditorGUILayout.Popup(lakePolygon.currentSplatMap, options); EditorGUILayout.EndHorizontal(); EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Lake curve changed"); } if (GUILayout.Button("Paint Terrain")) { TerrainPaint(); } } else { EditorGUILayout.Space(); EditorGUILayout.HelpBox("Terrain has no splatmaps.", MessageType.Info); } } else { EditorGUILayout.Space(); EditorGUILayout.HelpBox("No Terrain On Scene.", MessageType.Info); } #if VEGETATION_STUDIO EditorGUILayout.Space(); GUILayout.Label("Vegetation Studio: ", EditorStyles.boldLabel); EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); lakePolygon.vegetationMaskResolution = EditorGUILayout.Slider("Mask Resolution", lakePolygon.vegetationMaskResolution, 0.1f, 1); lakePolygon.vegetationMaskPerimeter = EditorGUILayout.FloatField("Vegetation Mask Perimeter", lakePolygon.vegetationMaskPerimeter); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Lake curve changed"); RegenerateVegetationMask(); } EditorGUI.indentLevel--; if (lakePolygon.vegetationMaskArea == null && GUILayout.Button("Add Vegetation Mask Area")) { lakePolygon.vegetationMaskArea = lakePolygon.gameObject.AddComponent <VegetationMaskArea>(); RegenerateVegetationMask(); } if (lakePolygon.vegetationMaskArea != null && GUILayout.Button("Calculate hull outline")) { RegenerateVegetationMask(); } #endif #if VEGETATION_STUDIO_PRO EditorGUILayout.Space(); GUILayout.Label("Vegetation Studio Pro: ", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); lakePolygon.vegetationBlendDistance = EditorGUILayout.FloatField("Vegetation Blend Distance", lakePolygon.vegetationBlendDistance); lakePolygon.biomMaskResolution = EditorGUILayout.Slider("Mask Resolution", lakePolygon.biomMaskResolution, 0.1f, 1); if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(lakePolygon, "Lake curve changed"); RegenerateBiomMask(); } if (lakePolygon.biomeMaskArea != null) { lakePolygon.refreshMask = EditorGUILayout.Toggle("Auto Refresh Biome Mask", lakePolygon.refreshMask); } if (GUILayout.Button("Add Vegetation Biom Mask Area")) { lakePolygon.GeneratePolygon(); if (lakePolygon.biomeMaskArea == null) { GameObject maskObject = new GameObject("MyMask"); maskObject.transform.SetParent(lakePolygon.transform); maskObject.transform.localPosition = Vector3.zero; lakePolygon.biomeMaskArea = maskObject.AddComponent <BiomeMaskArea>(); } if (lakePolygon.biomeMaskArea == null) { return; } RegenerateBiomMask(false); } #endif }
static public void CreatelakePolygon() { Selection.activeGameObject = LakePolygon.CreatePolygon(AssetDatabase.GetBuiltinExtraResource <Material>("Default-Diffuse.mat")).gameObject; }
public void CreateLake(BiomeMaskArea mask, string gameObjectName, List <Vector3> nodes) { #if RAM_2019 LakePolygon lakePolygon = RamLakeCreator.CreateLakePolygon(editor.extension.lakeSettings, mask, mask.transform.gameObject, gameObjectName, nodes); #endif }
/// <summary> /// Create a lake and re-parent the mask so that the lake becomes the child of the container and the mask the child of the lake. /// /// Note: the lake uses a bezier curve on the points, so the lake most likely won't be 100% in line with the mask. /// </summary> /// <param name="maskGameObject"></param> /// <param name="gameObjectName"></param> /// <param name="nodes"></param> public static LakePolygon CreateLakePolygon(LakeSettings lakeSettings, BiomeMaskArea mask, GameObject maskGameObject, string gameObjectName, List <Vector3> nodes) { GameObject maskParentGameObject = maskGameObject.transform.parent.gameObject; Vector3 maskPosition = maskGameObject.transform.position; // lake LakePolygon lakePolygon = LakePolygon.CreatePolygon(AssetDatabase.GetBuiltinExtraResource <Material>("Default-Diffuse.mat")); // apply profile lakePolygon.currentProfile = lakeSettings.lakeProfile; // apply gameobject data lakePolygon.transform.localPosition = Vector3.zero; lakePolygon.name = "Lake " + gameObjectName; // add biome nodes if (lakeSettings.ramInternalLakeCreation) { // apply settings lakePolygon.angleSimulation = lakeSettings.angleSimulation; lakePolygon.closeDistanceSimulation = lakeSettings.closeDistanceSimulation; lakePolygon.checkDistanceSimulation = lakeSettings.checkDistanceSimulation; lakePolygon.removeFirstPointSimulation = lakeSettings.removeFirstPointSimulation; // add point lakePolygon.AddPoint(maskPosition); // start simulation lakePolygon.Simulation(); } // use mask shape else { foreach (Vector3 node in nodes) { lakePolygon.AddPoint(maskParentGameObject.transform.InverseTransformPoint(node)); } } // generate the lake lakePolygon.GeneratePolygon(); // re-parent the mask to the lake and the lake to the parent GameObjectUtility.SetParentAndAlign(lakePolygon.gameObject, maskParentGameObject); GameObjectUtility.SetParentAndAlign(maskGameObject, lakePolygon.gameObject); // adjust the lake position lakePolygon.transform.position = maskPosition; // reset the mask position, it's now a child of the lake if (lakeSettings.ramInternalLakeCreation) { maskGameObject.transform.position = Vector3.zero; List <Vector3> newPoints = new List <Vector3>(); foreach (Vector3 node in lakePolygon.points) { newPoints.Add(lakePolygon.transform.TransformPoint(node)); } // set the lake's polygon as new mask nodes SetMaskNodes(mask, newPoints); // put move handle into the center of the polygon BiomeMaskUtils.CenterMainHandle(mask); } // re-apply the material so that the water becomes immediately visible MeshRenderer meshRenderer = lakePolygon.GetComponent <MeshRenderer>(); meshRenderer.sharedMaterial = lakePolygon.currentProfile.lakeMaterial; /* carving is disabled for now * if ( extension.lakeSettings.carveTerrain) * { * Debug.Log("Start carve"); * lakePolygon.terrainSmoothMultiplier = 2f; * lakePolygon.distSmooth = 10f; * lakePolygon.TerrainCarve(); * } */ // EditorUtility.SetDirty(lakePolygon); return(lakePolygon); }