using System.IO; using UnityEditor; using UnityEditor.AssetImporters; using UnityEngine; namespace zz.water.editor { [ScriptedImporter(1, FILE_EXTENSION)] public class WaterMeshImporter : ScriptedImporter { private const string FILE_EXTENSION = "zwatermesh"; [SerializeField] public WaterMesh waterMesh = new WaterMesh(); public override void OnImportAsset(AssetImportContext context) { waterMesh.Rebuild(); context.AddObjectToAsset("mesh", waterMesh.mesh); context.SetMainObject(waterMesh.mesh); } //Handles correct behaviour when double-clicking a .watermesh asset assigned to a field //Otherwise the OS prompts to open it [UnityEditor.Callbacks.OnOpenAsset] public static bool OnOpenAsset(int instanceID, int line) { Object target = EditorUtility.InstanceIDToObject(instanceID); if (target is Mesh) { var path = AssetDatabase.GetAssetPath(instanceID); if (Path.GetExtension(path) != "." + FILE_EXTENSION) return false; Selection.activeObject = target; return true; } return false; } } [CustomEditor(typeof(WaterMeshImporter))] public class WaterMeshImporterEditor: ScriptedImporterEditor { private SerializedProperty waterMesh; private SerializedProperty shape; private SerializedProperty scale; private SerializedProperty UVTiling; private SerializedProperty vertexDistance; private SerializedProperty noise; private SerializedProperty boundsPadding; private WaterMeshImporter importer; private bool autoApplyChanges; public override void OnEnable() { base.OnEnable(); importer = (WaterMeshImporter)target; waterMesh = serializedObject.FindProperty("waterMesh"); shape = waterMesh.FindPropertyRelative("shape"); scale = waterMesh.FindPropertyRelative("scale"); UVTiling = waterMesh.FindPropertyRelative("UVTiling"); vertexDistance = waterMesh.FindPropertyRelative("vertexDistance"); noise = waterMesh.FindPropertyRelative("noise"); boundsPadding = waterMesh.FindPropertyRelative("boundsPadding"); } public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); EditorGUILayout.PropertyField(shape); EditorGUILayout.Space(); EditorGUILayout.PropertyField(scale); EditorGUILayout.PropertyField(vertexDistance); int subdivisions = Mathf.FloorToInt(scale.floatValue / vertexDistance.floatValue); int vertexCount = Mathf.FloorToInt(subdivisions * subdivisions); using (new EditorGUILayout.HorizontalScope()) { GUILayout.Space(EditorGUIUtility.labelWidth); Rect rect = EditorGUILayout.GetControlRect(); EditorGUI.ProgressBar(rect, (float)vertexCount/65535f, $"Vertex count: {vertexCount:N1}/{65535f:N1}"); } if(vertexCount > 65535) { EditorGUILayout.HelpBox("Vertex count (" + vertexCount + ") is too high. Decrease the scale, or increase the vertex distance.", MessageType.Error); } EditorGUILayout.Space(); EditorGUILayout.PropertyField(UVTiling); EditorGUILayout.PropertyField(noise); EditorGUILayout.PropertyField(boundsPadding); EditorGUILayout.Space(); autoApplyChanges = EditorGUILayout.Toggle("Auto-apply changes", autoApplyChanges); if (EditorGUI.EndChangeCheck()) { serializedObject.ApplyModifiedProperties(); if (autoApplyChanges && HasModified()) { #if UNITY_2022_2_OR_NEWER this.SaveChanges(); #else this.ApplyAndImport(); #endif importer = (WaterMeshImporter)target; } } this.ApplyRevertGUI(); } } }