您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
189 行
8.4 KiB
189 行
8.4 KiB
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using WaterSystem;
|
|
|
|
[CustomEditor(typeof(Water))]
|
|
public class WaterEditor : Editor
|
|
{
|
|
GUIStyle largeFont = new GUIStyle();
|
|
//Wave editor
|
|
|
|
[SerializeField]
|
|
ReorderableList waveList;
|
|
|
|
private void OnEnable()
|
|
{
|
|
largeFont.fontStyle = FontStyle.Bold;
|
|
if (EditorGUIUtility.isProSkin)
|
|
largeFont.normal.textColor = Color.white;
|
|
else
|
|
largeFont.normal.textColor = Color.black;
|
|
//Reorderable list stuff////////////////////////////////////////////////
|
|
waveList = new ReorderableList(serializedObject, serializedObject.FindProperty("_waves"), false, true, true, true);
|
|
|
|
waveList.drawElementCallback =
|
|
(Rect rect, int index, bool isActive, bool isFocused) =>
|
|
{
|
|
var element = waveList.serializedProperty.GetArrayElementAtIndex(index);
|
|
rect.y += 2;
|
|
|
|
//Rects
|
|
Rect ampRect = new Rect(rect.x, rect.y, rect.width * 0.5f, EditorGUIUtility.singleLineHeight);
|
|
Rect dirRect = new Rect(ampRect.x + ampRect.width + 2f, rect.y, rect.width * 0.25f, EditorGUIUtility.singleLineHeight);
|
|
Rect lengthRect = new Rect(dirRect.x + dirRect.width + 2f, rect.y, rect.width * 0.25f, EditorGUIUtility.singleLineHeight);
|
|
|
|
EditorGUIUtility.labelWidth = 70f;
|
|
var waveAmp = element.FindPropertyRelative("amplitude");
|
|
waveAmp.floatValue = EditorGUI.Slider(ampRect, "Wave Height", waveAmp.floatValue, 0.01f, 8f);
|
|
EditorGUIUtility.labelWidth = 55f;
|
|
var waveDir = element.FindPropertyRelative("direction");
|
|
waveDir.floatValue = EditorGUI.FloatField(dirRect, "Direction", waveDir.floatValue);
|
|
EditorGUIUtility.labelWidth = 55f;
|
|
var waveLen = element.FindPropertyRelative("wavelength");
|
|
waveLen.floatValue = EditorGUI.FloatField(lengthRect, "Length", waveLen.floatValue);
|
|
};
|
|
//On can remove
|
|
waveList.onCanRemoveCallback = (ReorderableList l) =>
|
|
{
|
|
return l.count > 1;
|
|
};
|
|
//On remove
|
|
waveList.onRemoveCallback = (ReorderableList l) =>
|
|
{
|
|
if (EditorUtility.DisplayDialog("Warning!",
|
|
"Are you sure you want to delete the wave?", "Yes", "No"))
|
|
{
|
|
ReorderableList.defaultBehaviours.DoRemoveButton(l);
|
|
}
|
|
};
|
|
//On add
|
|
waveList.onAddCallback = (ReorderableList l) =>
|
|
{
|
|
var index = l.serializedProperty.arraySize;
|
|
if (index < 10)
|
|
{
|
|
l.serializedProperty.arraySize++;
|
|
l.index = index;
|
|
var element = l.serializedProperty.GetArrayElementAtIndex(index);
|
|
element.FindPropertyRelative("amplitude").floatValue = 0.5f;
|
|
element.FindPropertyRelative("direction").floatValue = Random.Range(-10f, 10f);
|
|
element.FindPropertyRelative("wavelength").floatValue = Random.Range(2f, 8f);
|
|
}
|
|
else
|
|
{
|
|
EditorUtility.DisplayDialog("Warning!", "You have reached the limit of 10 waves for this Water.", "Close");
|
|
}
|
|
};
|
|
//Draw header
|
|
waveList.drawHeaderCallback = (Rect rect) =>
|
|
{
|
|
EditorGUI.LabelField(rect, "Waves");
|
|
};
|
|
}
|
|
|
|
public override void OnInspectorGUI()
|
|
{
|
|
serializedObject.Update();
|
|
Water w = target as Water;
|
|
|
|
//Draw global water settings
|
|
GUILayout.Space(1f);
|
|
EditorGUILayout.LabelField("General Settings", largeFont);
|
|
|
|
var maxDepth = serializedObject.FindProperty("_waterMaxDepth");
|
|
EditorGUILayout.PropertyField(maxDepth, new GUIContent("Maximum Visibility", maxDepthTT), true, null);
|
|
var absorpRamp = serializedObject.FindProperty("_absorptionRampRaw");
|
|
EditorGUILayout.PropertyField(absorpRamp, new GUIContent("Absorption Color", colorRampTT), true, null);
|
|
var scatterRamp = serializedObject.FindProperty("_scatterRampRaw");
|
|
EditorGUILayout.PropertyField(scatterRamp, new GUIContent("Scattering Color", colorRampTT), true, null);
|
|
|
|
//Draw wave settings
|
|
GUILayout.Space(1f);
|
|
EditorGUILayout.LabelField("Wave Settings", largeFont);
|
|
|
|
var customWaves = serializedObject.FindProperty("_customWaves");
|
|
customWaves.boolValue = EditorGUILayout.Toggle("Custom Waves", customWaves.boolValue);
|
|
if (customWaves.boolValue)
|
|
{
|
|
waveList.DoLayoutList();
|
|
}
|
|
else
|
|
{
|
|
var waveSetting = serializedObject.FindProperty("_basicWaveSettings");
|
|
var waveNum = waveSetting.FindPropertyRelative("numWaves");
|
|
waveNum.intValue = EditorGUILayout.Popup("Number of Wave Layers", waveNum.intValue, numWavesOptions);
|
|
var waveRough = waveSetting.FindPropertyRelative("amplitude");
|
|
waveRough.floatValue = EditorGUILayout.Slider(new GUIContent("Wave Height(Average)"), waveRough.floatValue, 0.1f, 8f);
|
|
var waveDir = waveSetting.FindPropertyRelative("direction");
|
|
waveDir.floatValue = EditorGUILayout.Slider(new GUIContent("Wind Direction"), waveDir.floatValue, 0f, 360f);
|
|
var waveLen = waveSetting.FindPropertyRelative("wavelength");
|
|
waveLen.floatValue = EditorGUILayout.Slider(new GUIContent("Wavelength(Average)"), waveLen.floatValue, 2f, 30f);
|
|
if (GUILayout.Button("Randomize Waves"))
|
|
{
|
|
var randSeed = serializedObject.FindProperty("randomSeed");
|
|
randSeed.intValue = System.DateTime.Now.Millisecond;
|
|
}
|
|
}
|
|
|
|
var waveDebug = serializedObject.FindProperty("_debugMode");
|
|
EditorGUILayout.PropertyField(waveDebug);
|
|
|
|
serializedObject.ApplyModifiedProperties();
|
|
|
|
if(GUI.changed)
|
|
{
|
|
w.ToggleBasicWaves(customWaves.boolValue);
|
|
w.Init();
|
|
}
|
|
}
|
|
|
|
void OnSceneGUI()
|
|
{
|
|
Water w = target as Water;
|
|
Camera cam = SceneView.currentDrawingSceneView.camera;
|
|
var waveDebug = serializedObject.FindProperty("_debugMode");
|
|
if (cam && waveDebug.intValue != 0)
|
|
{
|
|
Vector3 pos = Vector3.zero;
|
|
float dist = 10f;
|
|
if (waveDebug.intValue == 2)
|
|
{
|
|
Plane p = new Plane(Vector3.zero, Vector3.forward, Vector3.right);
|
|
|
|
Ray r = Camera.current.ViewportPointToRay(new Vector2(0.25f, 0.25f));
|
|
if (p.Raycast(r, out dist))
|
|
{
|
|
pos = Camera.current.ViewportToWorldPoint(new Vector3(0.25f, 0.25f, dist));
|
|
}
|
|
}
|
|
|
|
for (int i = w._waves.Count - 1; i >= 0; i--)
|
|
{
|
|
Water.Wave wave = w._waves[i];
|
|
Random.InitState(i);
|
|
Color c = Color.HSVToRGB(Random.Range(0f, 1f), 1f, 1f);
|
|
c.a = Mathf.Clamp01(0.01f * dist - 0.1f) * 0.5f;
|
|
Handles.color = c;
|
|
pos.y = wave.amplitude;
|
|
DrawWaveGizmo(pos, wave.direction, wave.amplitude, wave.wavelength);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DrawWaveGizmo(Vector3 pos, float angle, float size, float length)
|
|
{
|
|
Handles.DrawSolidDisc(pos, Vector3.up, length / 2f);
|
|
Handles.ArrowHandleCap(0, pos, Quaternion.AngleAxis(angle, Vector3.up), -length / 1.75f, EventType.Repaint);
|
|
}
|
|
|
|
string[] numWavesOptions = new string[] { "1 wave(low)", "2 waves(low)", "3 waves(low)", "4 waves(medium)", "5 waves(medium)", "6 waves(default)", "7 waves(high)", "8 waves(high)", "9 waves(high)", "10 waves(max)" };
|
|
|
|
//Tooltips/////////////////////////////////////////////////
|
|
private string maxDepthTT = "This controls the max depth of the waters transparency, it also controls the visual color of the water based on depth.";
|
|
private string colorRampTT = "This gradient controls the colour of the water from shallow to deep, this will generate a ramp texture in the background and apply it to the water shader.";
|
|
private string waveDebugTT = "Debug settings for the waves, debug mode helps to visualize wave direction(arrow), wavelength(circle radius) and wave ampliture(Y offset).\nNone=No debug gizmos\nStatic=Draws wave debug gizmos at the world origin\nScreen=Draws the gizmos in the corner of the screen, they still keep world scale";
|
|
|
|
}
|