portals and dash. Also a bit of terrain building and level design
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77c593e5314781d4aa291761be14e03e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,184 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine.SocialPlatforms;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public class PAreaEditingGUIDrawer
|
||||
{
|
||||
private PWater water;
|
||||
|
||||
private int selectedAnchorIndex;
|
||||
|
||||
public PAreaEditingGUIDrawer(PWater water)
|
||||
{
|
||||
this.water = water;
|
||||
selectedAnchorIndex = -1;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (Event.current == null)
|
||||
return;
|
||||
HandleSelectTranslateRemoveAnchors();
|
||||
HandleAddAnchor();
|
||||
DrawInstruction();
|
||||
CatchHotControl();
|
||||
}
|
||||
|
||||
private void HandleSelectTranslateRemoveAnchors()
|
||||
{
|
||||
List<Vector3> localPositions = water.AreaMeshAnchors;
|
||||
if (localPositions.Count == 0)
|
||||
return;
|
||||
if (localPositions.Count >= 2)
|
||||
{
|
||||
List<Vector3> worldPositions = new List<Vector3>();
|
||||
for (int i = 0; i < localPositions.Count; ++i)
|
||||
{
|
||||
worldPositions.Add(water.transform.TransformPoint(localPositions[i]));
|
||||
}
|
||||
Handles.DrawPolyLine(worldPositions.ToArray());
|
||||
Handles.DrawLine(worldPositions[0], worldPositions[worldPositions.Count - 1]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < localPositions.Count; ++i)
|
||||
{
|
||||
Vector3 localPos = localPositions[i];
|
||||
Vector3 worldPos = water.transform.TransformPoint(localPos);
|
||||
float handleSize = HandleUtility.GetHandleSize(worldPos) * 0.2f;
|
||||
if (i == selectedAnchorIndex)
|
||||
{
|
||||
Handles.color = Handles.selectedColor;
|
||||
Handles.SphereHandleCap(0, worldPos, Quaternion.identity, handleSize, EventType.Repaint);
|
||||
worldPos = Handles.PositionHandle(worldPos, Quaternion.identity);
|
||||
localPos = water.transform.InverseTransformPoint(worldPos);
|
||||
localPos.y = 0;
|
||||
localPositions[i] = localPos;
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.color = Color.cyan;
|
||||
if (Handles.Button(worldPos, Quaternion.identity, handleSize, handleSize * 0.5f, Handles.SphereHandleCap))
|
||||
{
|
||||
if (Event.current.control)
|
||||
{
|
||||
selectedAnchorIndex = -1;
|
||||
localPositions.RemoveAt(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAnchorIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
|
||||
{
|
||||
selectedAnchorIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAddAnchor()
|
||||
{
|
||||
if (Event.current.type == EventType.MouseDown && Event.current.button == 0)
|
||||
{
|
||||
Plane plane = new Plane(Vector3.up, water.transform.position);
|
||||
Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
|
||||
float distance = -1;
|
||||
if (plane.Raycast(r, out distance))
|
||||
{
|
||||
Vector3 hitWorldPos = r.origin + r.direction * distance;
|
||||
Vector3 hitLocalPos = water.transform.InverseTransformPoint(hitWorldPos);
|
||||
if (Event.current.shift)
|
||||
{
|
||||
water.AreaMeshAnchors.Add(hitLocalPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void VisualizeIntersections()
|
||||
{
|
||||
if (water.AreaMeshAnchors.Count < 3)
|
||||
return;
|
||||
|
||||
Plane plane = new Plane(Vector3.up, water.transform.position);
|
||||
Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
|
||||
float distance = -1;
|
||||
if (plane.Raycast(r, out distance))
|
||||
{
|
||||
Vector3 hitWorldPos = r.origin + r.direction * distance;
|
||||
|
||||
float lineY = hitWorldPos.z;
|
||||
Handles.color = Color.red;
|
||||
Handles.DrawLine(new Vector3(-100, 0, lineY), new Vector3(100, 0, lineY));
|
||||
|
||||
List<Vector3> intersections = new List<Vector3>();
|
||||
List<Vector3> anchors = new List<Vector3>(water.AreaMeshAnchors);
|
||||
anchors.Add(water.AreaMeshAnchors[0]);
|
||||
for (int i = 0; i < anchors.Count - 1; ++i)
|
||||
{
|
||||
Vector3 a0 = anchors[i];
|
||||
Vector3 a1 = anchors[i + 1];
|
||||
Vector2 inter;
|
||||
if (PGeometryUtilities.IsIntersectHorizontalLine(a0.x, a0.z, a1.x, a1.z, lineY, out inter))
|
||||
{
|
||||
intersections.Add(new Vector3(inter.x, 0, inter.y));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < intersections.Count; ++i)
|
||||
{
|
||||
Handles.color = Color.red;
|
||||
Handles.CubeHandleCap(0, intersections[i], Quaternion.identity, 1, EventType.Repaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawInstruction()
|
||||
{
|
||||
string s = string.Format(
|
||||
"{0}" +
|
||||
"{1}" +
|
||||
"{2}" +
|
||||
"{3}",
|
||||
"Click to select,",
|
||||
"\nShift+Click to add,",
|
||||
"\nCtrl+Click to remove anchor.",
|
||||
"\nClick End Editing Tiles when done.");
|
||||
|
||||
GUIContent mouseMessage = new GUIContent(s);
|
||||
PEditorCommon.SceneViewMouseMessage(mouseMessage);
|
||||
}
|
||||
|
||||
private void CatchHotControl()
|
||||
{
|
||||
int controlId = GUIUtility.GetControlID(this.GetHashCode(), FocusType.Passive);
|
||||
if (Event.current.type == EventType.MouseDown)
|
||||
{
|
||||
if (Event.current.button == 0)
|
||||
{
|
||||
GUIUtility.hotControl = controlId;
|
||||
//OnMouseDown(Event.current);
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
if (GUIUtility.hotControl == controlId)
|
||||
{
|
||||
//OnMouseUp(Event.current);
|
||||
//Return the hot control back to Unity, use the default
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.KeyDown)
|
||||
{
|
||||
//OnKeyDown(Event.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2a8144486c5466742ba52c5dcef76990
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,63 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor.Callbacks;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
internal class PCompileLogger
|
||||
{
|
||||
private const string PACKAGE_NAME = "Poseidon - Low Poly Water System";
|
||||
private const string PACKAGE_NAME_PLACEHOLDER = "${PACKAGE_NAME}";
|
||||
|
||||
private const string WEBSITE = "http://pinwheel.studio";
|
||||
private const string WEBSITE_PLACEHOLDER = "${WEBSITE}";
|
||||
|
||||
private const string SUPPORT_MAIL = "support@pinwheel.studio";
|
||||
private const string SUPPORT_MAIL_PLACEHOLDER = "${SUPPORT_MAIL}";
|
||||
|
||||
private const string LINK_COLOR = "blue";
|
||||
private const string LINK_COLOR_PLACEHOLDER = "${LC}";
|
||||
|
||||
private const float LOG_MESSAGE_PROBABIILITY = 0.03F;
|
||||
private static string[] messages = new string[]
|
||||
{
|
||||
"Thanks for using the ${PACKAGE_NAME}, please contact <color=${LC}>${SUPPORT_MAIL}</color> for support!",
|
||||
"Thanks for using the ${PACKAGE_NAME}, please give it a 5-stars rating and a positive review on the store!"
|
||||
};
|
||||
|
||||
//[DidReloadScripts]
|
||||
public static void ShowMessageOnCompileSucceeded()
|
||||
{
|
||||
ValidatePackageAndNamespace();
|
||||
if (Random.value < LOG_MESSAGE_PROBABIILITY)
|
||||
{
|
||||
if (messages.Length == 0)
|
||||
return;
|
||||
int msgIndex = Random.Range(0, messages.Length);
|
||||
string msg = messages[msgIndex]
|
||||
.Replace(PACKAGE_NAME_PLACEHOLDER, PVersionInfo.ProductNameAndVersionShort)
|
||||
.Replace(WEBSITE_PLACEHOLDER, WEBSITE)
|
||||
.Replace(SUPPORT_MAIL_PLACEHOLDER, SUPPORT_MAIL)
|
||||
.Replace(LINK_COLOR_PLACEHOLDER, LINK_COLOR);
|
||||
Debug.Log(msg, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ValidatePackageAndNamespace()
|
||||
{
|
||||
bool isPackageNameInvalid = PACKAGE_NAME.Equals("PACKAGE_NAME");
|
||||
bool isNamespaceInvalid = typeof(PCompileLogger).Namespace.Contains("PACKAGE_NAME");
|
||||
if (isPackageNameInvalid)
|
||||
{
|
||||
string message = "<color=red>Invalid PACKAGE_NAME in CompileLogger, fix it before release!</color>";
|
||||
Debug.Log(message);
|
||||
}
|
||||
if (isNamespaceInvalid)
|
||||
{
|
||||
string message = "<color=red>Invalid NAMESPACE in CompileLogger, fix it before release!</color>";
|
||||
Debug.Log(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e965947bfaa45714a828aeb78f6f8190
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4bc1ffda7fc15ff4daf998b3db6956dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,133 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public static class PEditorMenus
|
||||
{
|
||||
[MenuItem("GameObject/3D Object/Poseidon/Calm Water")]
|
||||
public static PWater CreateCalmWaterObject(MenuCommand cmd)
|
||||
{
|
||||
GameObject g = new GameObject("Calm Water");
|
||||
if (cmd != null && cmd.context != null)
|
||||
{
|
||||
GameObject root = cmd.context as GameObject;
|
||||
GameObjectUtility.SetParentAndAlign(g, root);
|
||||
}
|
||||
|
||||
PWater waterComponent = g.AddComponent<PWater>();
|
||||
PWaterProfile profile = PWaterProfile.CreateInstance<PWaterProfile>();
|
||||
string fileName = "WaterProfile_" + PCommon.GetUniqueID();
|
||||
string filePath = string.Format("Assets/{0}.asset", fileName);
|
||||
AssetDatabase.CreateAsset(profile, filePath);
|
||||
|
||||
profile.CopyFrom(PPoseidonSettings.Instance.CalmWaterProfile);
|
||||
waterComponent.Profile = profile;
|
||||
waterComponent.TileSize = new Vector2(100, 100);
|
||||
|
||||
return waterComponent;
|
||||
}
|
||||
|
||||
[MenuItem("GameObject/3D Object/Poseidon/Calm Water HQ")]
|
||||
public static PWater CreateCalmWaterHQObject(MenuCommand cmd)
|
||||
{
|
||||
GameObject g = new GameObject("Calm Water HQ");
|
||||
if (cmd != null && cmd.context != null)
|
||||
{
|
||||
GameObject root = cmd.context as GameObject;
|
||||
GameObjectUtility.SetParentAndAlign(g, root);
|
||||
}
|
||||
|
||||
PWater waterComponent = g.AddComponent<PWater>();
|
||||
PWaterProfile profile = PWaterProfile.CreateInstance<PWaterProfile>();
|
||||
string fileName = "WaterProfile_" + PCommon.GetUniqueID();
|
||||
string filePath = string.Format("Assets/{0}.asset", fileName);
|
||||
AssetDatabase.CreateAsset(profile, filePath);
|
||||
|
||||
profile.CopyFrom(PPoseidonSettings.Instance.CalmWaterHQProfile);
|
||||
waterComponent.Profile = profile;
|
||||
waterComponent.TileSize = new Vector2(100, 100);
|
||||
|
||||
return waterComponent;
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Project/Settings")]
|
||||
public static void ShowSettings()
|
||||
{
|
||||
Selection.activeObject = PPoseidonSettings.Instance;
|
||||
EditorGUIUtility.PingObject(PPoseidonSettings.Instance);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Project/Update Dependencies")]
|
||||
public static void UpdateDependencies()
|
||||
{
|
||||
PPackageInitializer.Init();
|
||||
PWaterShaderProvider.ResetShaderReferences();
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Project/Version Info")]
|
||||
public static void ShowVersionInfo()
|
||||
{
|
||||
EditorUtility.DisplayDialog(
|
||||
"Version Info",
|
||||
PVersionInfo.ProductNameAndVersion,
|
||||
"OK");
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Learning Resources/Online Manual")]
|
||||
public static void ShowOnlineUserGuide()
|
||||
{
|
||||
Application.OpenURL(PCommon.ONLINE_MANUAL);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Learning Resources/Youtube Channel")]
|
||||
public static void ShowYoutubeChannel()
|
||||
{
|
||||
Application.OpenURL(PCommon.YOUTUBE_CHANNEL);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Learning Resources/Facebook Page")]
|
||||
public static void ShowFacebookPage()
|
||||
{
|
||||
Application.OpenURL(PCommon.FACEBOOK_PAGE);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Community/Forum")]
|
||||
public static void ShowForum()
|
||||
{
|
||||
Application.OpenURL(PCommon.FORUM);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Community/Discord")]
|
||||
public static void ShowDiscord()
|
||||
{
|
||||
Application.OpenURL(PCommon.DISCORD);
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Contact/Support")]
|
||||
public static void ShowSupportEmailEditor()
|
||||
{
|
||||
PEditorCommon.OpenEmailEditor(
|
||||
PCommon.SUPPORT_EMAIL,
|
||||
"[Poseidon] SHORT_QUESTION_HERE",
|
||||
"YOUR_QUESTION_IN_DETAIL");
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Contact/Business")]
|
||||
public static void ShowBusinessEmailEditor()
|
||||
{
|
||||
PEditorCommon.OpenEmailEditor(
|
||||
PCommon.BUSINESS_EMAIL,
|
||||
"[Poseidon] SHORT_MESSAGE_HERE",
|
||||
"YOUR_MESSAGE_IN_DETAIL");
|
||||
}
|
||||
|
||||
[MenuItem("Window/Poseidon/Write a Review")]
|
||||
public static void OpenStorePage()
|
||||
{
|
||||
Application.OpenURL("http://u3d.as/1CsU");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4814c4364842e0a4a8a38e90ee72c35a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,102 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public static class PPackageInitializer
|
||||
{
|
||||
public static string POSEIDON_KW = "POSEIDON";
|
||||
public static string POSEIDON_URP_KW = "POSEIDON_URP";
|
||||
|
||||
private static ListRequest listPackageRequest = null;
|
||||
#pragma warning disable 0414
|
||||
private static bool isUrpInstalled = false;
|
||||
private static bool isShaderGraphInstalled = false;
|
||||
#pragma warning restore 0414
|
||||
|
||||
[DidReloadScripts]
|
||||
public static void Init()
|
||||
{
|
||||
isUrpInstalled = false;
|
||||
isShaderGraphInstalled = false;
|
||||
|
||||
CheckUnityPackagesAndInit();
|
||||
}
|
||||
|
||||
private static void CheckUnityPackagesAndInit()
|
||||
{
|
||||
listPackageRequest = Client.List(true);
|
||||
EditorApplication.update += OnRequestingPackageList;
|
||||
}
|
||||
|
||||
private static void OnRequestingPackageList()
|
||||
{
|
||||
if (listPackageRequest == null)
|
||||
return;
|
||||
if (!listPackageRequest.IsCompleted)
|
||||
return;
|
||||
if (listPackageRequest.Error != null)
|
||||
{
|
||||
isUrpInstalled = false;
|
||||
isShaderGraphInstalled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
isUrpInstalled = false;
|
||||
isShaderGraphInstalled = false;
|
||||
foreach (UnityEditor.PackageManager.PackageInfo p in listPackageRequest.Result)
|
||||
{
|
||||
if (p.name.Equals("com.unity.render-pipelines.universal"))
|
||||
{
|
||||
isUrpInstalled = true;
|
||||
}
|
||||
if (p.name.Equals("com.unity.shadergraph"))
|
||||
{
|
||||
isShaderGraphInstalled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorApplication.update -= OnRequestingPackageList;
|
||||
InitPackage();
|
||||
}
|
||||
|
||||
private static void InitPackage()
|
||||
{
|
||||
BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
BuildTargetGroup buildGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
|
||||
|
||||
string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildGroup);
|
||||
List<string> symbolList = new List<string>(symbols.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
bool isDirty = false;
|
||||
if (!symbolList.Contains(POSEIDON_KW))
|
||||
{
|
||||
symbolList.Add(POSEIDON_KW);
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
if (isUrpInstalled && !symbolList.Contains(POSEIDON_URP_KW))
|
||||
{
|
||||
symbolList.Add(POSEIDON_URP_KW);
|
||||
isDirty = true;
|
||||
}
|
||||
else if (!isUrpInstalled && symbolList.Contains(POSEIDON_URP_KW))
|
||||
{
|
||||
symbolList.RemoveAll(s => s.Equals(POSEIDON_URP_KW));
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
if (isDirty)
|
||||
{
|
||||
symbols = symbolList.ListElementsToString(";");
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildGroup, symbols);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 24fc572b506f66a4b93162a883aaaea1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public struct PSelectionGridArgs
|
||||
{
|
||||
public ICollection collection;
|
||||
public int selectedIndex;
|
||||
public Vector2 tileSize;
|
||||
|
||||
public delegate void DrawHandler(Rect r, object o);
|
||||
public DrawHandler drawPreviewFunction;
|
||||
public DrawHandler drawLabelFunction;
|
||||
public DrawHandler customDrawFunction;
|
||||
|
||||
public delegate object CategorizeHandler(object o);
|
||||
public CategorizeHandler categorizeFunction;
|
||||
|
||||
public delegate string TooltipHandler(object o);
|
||||
public TooltipHandler tooltipFunction;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ab1fccc6c07924419849c24c11e351e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,364 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public class PSplineEditingGUIDrawer
|
||||
{
|
||||
private const float BEZIER_SELECT_DISTANCE = 10;
|
||||
private const float BEZIER_WIDTH = 5;
|
||||
|
||||
private PWater water;
|
||||
|
||||
public int selectedAnchorIndex = -1;
|
||||
public int selectedSegmentIndex = -1;
|
||||
|
||||
public PSplineEditingGUIDrawer(PWater water)
|
||||
{
|
||||
this.water = water;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (Event.current == null)
|
||||
return;
|
||||
|
||||
//DrawDebug();
|
||||
|
||||
HandleSelectTransformRemoveAnchor();
|
||||
HandleSelectTransformRemoveSegment();
|
||||
HandleAddAnchor();
|
||||
|
||||
DrawPivot();
|
||||
DrawInstruction();
|
||||
CatchHotControl();
|
||||
}
|
||||
|
||||
private void HandleSelectTransformRemoveAnchor()
|
||||
{
|
||||
List<PSplineAnchor> anchors = water.Spline.Anchors;
|
||||
|
||||
for (int i = 0; i < anchors.Count; ++i)
|
||||
{
|
||||
PSplineAnchor a = anchors[i];
|
||||
Vector3 localPos = a.Position;
|
||||
Vector3 worldPos = water.transform.TransformPoint(localPos);
|
||||
float handleSize = HandleUtility.GetHandleSize(worldPos) * 0.2f;
|
||||
if (i == selectedAnchorIndex)
|
||||
{
|
||||
Handles.color = Handles.selectedColor;
|
||||
Handles.SphereHandleCap(0, worldPos, Quaternion.identity, handleSize, EventType.Repaint);
|
||||
bool isGlobalRotation = Tools.pivotRotation == PivotRotation.Global;
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
if (Tools.current == Tool.Move)
|
||||
{
|
||||
worldPos = Handles.PositionHandle(worldPos, isGlobalRotation ? Quaternion.identity : a.Rotation);
|
||||
localPos = water.transform.InverseTransformPoint(worldPos);
|
||||
a.Position = localPos;
|
||||
}
|
||||
else if (Tools.current == Tool.Rotate && !PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
a.Rotation = Handles.RotationHandle(a.Rotation, worldPos);
|
||||
}
|
||||
else if (Tools.current == Tool.Scale)
|
||||
{
|
||||
a.Scale = Handles.ScaleHandle(a.Scale, worldPos, isGlobalRotation ? Quaternion.identity : a.Rotation, HandleUtility.GetHandleSize(worldPos));
|
||||
}
|
||||
anchors[i] = a;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
water.Spline.SmoothTangents(selectedAnchorIndex);
|
||||
}
|
||||
List<int> segmentIndices = water.Spline.FindSegments(selectedAnchorIndex);
|
||||
water.GenerateSplineMeshAtSegments(segmentIndices);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.color = Color.cyan;
|
||||
if (Handles.Button(worldPos, Quaternion.identity, handleSize, handleSize * 0.5f, Handles.SphereHandleCap))
|
||||
{
|
||||
if (Event.current.control)
|
||||
{
|
||||
selectedAnchorIndex = -1;
|
||||
selectedSegmentIndex = -1;
|
||||
water.Spline.RemoveAnchor(i);
|
||||
}
|
||||
else if (Event.current.shift)
|
||||
{
|
||||
if (selectedAnchorIndex != i &&
|
||||
selectedAnchorIndex >= 0 &&
|
||||
selectedAnchorIndex < anchors.Count)
|
||||
{
|
||||
water.Spline.AddSegment(selectedAnchorIndex, i);
|
||||
if (PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
int[] segmentsIndices = water.Spline.SmoothTangents(selectedAnchorIndex, i);
|
||||
water.GenerateSplineMeshAtSegments(segmentsIndices);
|
||||
}
|
||||
else
|
||||
{
|
||||
water.GenerateSplineMeshAtSegment(water.Spline.Segments.Count - 1);
|
||||
}
|
||||
selectedAnchorIndex = i;
|
||||
selectedSegmentIndex = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAnchorIndex = i;
|
||||
selectedSegmentIndex = -1;
|
||||
}
|
||||
Event.current.Use();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAddAnchor()
|
||||
{
|
||||
bool isLeftMouseUp = Event.current.type == EventType.MouseUp && Event.current.button == 0;
|
||||
bool isShift = Event.current.shift;
|
||||
if (!isLeftMouseUp)
|
||||
return;
|
||||
int raycastLayer = PSplineToolConfig.Instance.RaycastLayer;
|
||||
Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
|
||||
RaycastHit hit;
|
||||
if (Physics.Raycast(r, out hit, 10000, LayerMask.GetMask(LayerMask.LayerToName(raycastLayer))))
|
||||
{
|
||||
if (!isShift)
|
||||
{
|
||||
selectedAnchorIndex = -1;
|
||||
return;
|
||||
}
|
||||
Vector3 offset = Vector3.up * PSplineToolConfig.Instance.YOffset;
|
||||
Vector3 worldPos = hit.point + offset;
|
||||
Vector3 localPos = water.transform.InverseTransformPoint(worldPos);
|
||||
PSplineAnchor a = new PSplineAnchor(localPos);
|
||||
water.Spline.AddAnchor(a);
|
||||
|
||||
if (selectedAnchorIndex >= 0 && selectedAnchorIndex < water.Spline.Anchors.Count - 1)
|
||||
{
|
||||
water.Spline.AddSegment(selectedAnchorIndex, water.Spline.Anchors.Count - 1);
|
||||
if (PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
int[] segmentIndices = water.Spline.SmoothTangents(selectedAnchorIndex, water.Spline.Anchors.Count - 1);
|
||||
water.GenerateSplineMeshAtSegments(segmentIndices);
|
||||
}
|
||||
else
|
||||
{
|
||||
water.GenerateSplineMeshAtSegment(water.Spline.Segments.Count - 1);
|
||||
}
|
||||
}
|
||||
|
||||
selectedAnchorIndex = water.Spline.Anchors.Count - 1;
|
||||
Event.current.Use();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedAnchorIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSelectTransformRemoveSegment()
|
||||
{
|
||||
List<PSplineSegment> segments = water.Spline.Segments;
|
||||
List<PSplineAnchor> anchors = water.Spline.Anchors;
|
||||
for (int i = 0; i < segments.Count; ++i)
|
||||
{
|
||||
if (!water.Spline.IsSegmentValid(i))
|
||||
continue;
|
||||
if (i == selectedSegmentIndex && !PSplineToolConfig.Instance.AutoTangent)
|
||||
HandleSelectedSegmentModifications();
|
||||
int i0 = segments[i].StartIndex;
|
||||
int i1 = segments[i].EndIndex;
|
||||
PSplineAnchor a0 = anchors[i0];
|
||||
PSplineAnchor a1 = anchors[i1];
|
||||
Vector3 startPosition = water.transform.TransformPoint(a0.Position);
|
||||
Vector3 endPosition = water.transform.TransformPoint(a1.Position);
|
||||
Vector3 startTangent = water.transform.TransformPoint(segments[i].StartTangent);
|
||||
Vector3 endTangent = water.transform.TransformPoint(segments[i].EndTangent);
|
||||
Color color = (i == selectedSegmentIndex) ?
|
||||
Handles.selectedColor :
|
||||
Color.white;
|
||||
Color colorFade = new Color(color.r, color.g, color.b, color.a * 0.1f);
|
||||
|
||||
Vector3[] bezierPoints = Handles.MakeBezierPoints(startPosition, endPosition, startTangent, endTangent, 11);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;
|
||||
Handles.color = color;
|
||||
Handles.DrawAAPolyLine(BEZIER_WIDTH, bezierPoints);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Greater;
|
||||
Handles.color = colorFade;
|
||||
Handles.DrawAAPolyLine(BEZIER_WIDTH, bezierPoints);
|
||||
|
||||
Matrix4x4 localToWorld = water.transform.localToWorldMatrix;
|
||||
Matrix4x4 splineToLocal = water.Spline.TRS(i, 0.5f);
|
||||
Matrix4x4 splineToWorld = localToWorld * splineToLocal;
|
||||
Vector3 arrow0 = splineToWorld.MultiplyPoint(Vector3.zero);
|
||||
splineToLocal = water.Spline.TRS(i, 0.45f);
|
||||
splineToWorld = localToWorld * splineToLocal;
|
||||
Vector3 arrow1 = splineToWorld.MultiplyPoint(Vector3.left * 0.5f);
|
||||
Vector3 arrow2 = splineToWorld.MultiplyPoint(Vector3.right * 0.5f);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;
|
||||
Handles.color = color;
|
||||
Handles.DrawAAPolyLine(BEZIER_WIDTH, arrow1, arrow0, arrow2);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Greater;
|
||||
Handles.color = colorFade;
|
||||
Handles.DrawAAPolyLine(BEZIER_WIDTH, arrow1, arrow0, arrow2);
|
||||
|
||||
if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
|
||||
{
|
||||
float d0 = DistanceMouseToSpline(Event.current.mousePosition, bezierPoints);
|
||||
float d1 = DistanceMouseToPoint(Event.current.mousePosition, bezierPoints[0]);
|
||||
float d2 = DistanceMouseToPoint(Event.current.mousePosition, bezierPoints[bezierPoints.Length - 1]);
|
||||
if (d0 <= BEZIER_SELECT_DISTANCE &&
|
||||
d1 > BEZIER_SELECT_DISTANCE &&
|
||||
d2 > BEZIER_SELECT_DISTANCE)
|
||||
{
|
||||
selectedSegmentIndex = i;
|
||||
if (Event.current.control)
|
||||
{
|
||||
water.Spline.RemoveSegment(selectedSegmentIndex);
|
||||
selectedSegmentIndex = -1;
|
||||
GUI.changed = true;
|
||||
}
|
||||
//don't Use() the event here
|
||||
}
|
||||
else
|
||||
{
|
||||
if (selectedSegmentIndex == i)
|
||||
{
|
||||
selectedSegmentIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Always;
|
||||
}
|
||||
|
||||
private void HandleSelectedSegmentModifications()
|
||||
{
|
||||
if (selectedSegmentIndex < 0 || selectedSegmentIndex >= water.Spline.Segments.Count)
|
||||
return;
|
||||
if (!water.Spline.IsSegmentValid(selectedSegmentIndex))
|
||||
return;
|
||||
PSplineSegment segment = water.Spline.Segments[selectedSegmentIndex];
|
||||
PSplineAnchor startAnchor = water.Spline.Anchors[segment.StartIndex];
|
||||
PSplineAnchor endAnchor = water.Spline.Anchors[segment.EndIndex];
|
||||
|
||||
Vector3 worldStartPosition = water.transform.TransformPoint(startAnchor.Position);
|
||||
Vector3 worldEndPosition = water.transform.TransformPoint(endAnchor.Position);
|
||||
Vector3 worldStartTangent = water.transform.TransformPoint(segment.StartTangent);
|
||||
Vector3 worldEndTangent = water.transform.TransformPoint(segment.EndTangent);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Always;
|
||||
worldStartTangent = Handles.PositionHandle(worldStartTangent, Quaternion.identity);
|
||||
worldEndTangent = Handles.PositionHandle(worldEndTangent, Quaternion.identity);
|
||||
|
||||
segment.StartTangent = water.transform.InverseTransformPoint(worldStartTangent);
|
||||
segment.EndTangent = water.transform.InverseTransformPoint(worldEndTangent);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.GenerateSplineMeshAtSegment(selectedSegmentIndex);
|
||||
}
|
||||
|
||||
Handles.color = Color.white;
|
||||
Handles.DrawLine(worldStartPosition, worldStartTangent);
|
||||
Handles.DrawLine(worldEndPosition, worldEndTangent);
|
||||
}
|
||||
|
||||
private void DrawPivot()
|
||||
{
|
||||
Vector3 pivot = water.transform.position;
|
||||
float size = HandleUtility.GetHandleSize(pivot);
|
||||
|
||||
Vector3 xStart = pivot + Vector3.left * size;
|
||||
Vector3 xEnd = pivot + Vector3.right * size;
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Always;
|
||||
Handles.color = Handles.xAxisColor;
|
||||
Handles.DrawLine(xStart, xEnd);
|
||||
|
||||
Vector3 yStart = pivot + Vector3.down * size;
|
||||
Vector3 yEnd = pivot + Vector3.up * size;
|
||||
Handles.color = Handles.yAxisColor;
|
||||
Handles.DrawLine(yStart, yEnd);
|
||||
|
||||
Vector3 zStart = pivot + Vector3.back * size;
|
||||
Vector3 zEnd = pivot + Vector3.forward * size;
|
||||
Handles.color = Handles.zAxisColor;
|
||||
Handles.DrawLine(zStart, zEnd);
|
||||
}
|
||||
|
||||
private void DrawInstruction()
|
||||
{
|
||||
string s = string.Format(
|
||||
"{0}" +
|
||||
"{1}" +
|
||||
"{2}" +
|
||||
"{3}",
|
||||
"Click to select,",
|
||||
"\nShift+Click to add,",
|
||||
"\nCtrl+Click to remove anchor.",
|
||||
"\nClick End Editing Spline when done.");
|
||||
|
||||
GUIContent mouseMessage = new GUIContent(s);
|
||||
PEditorCommon.SceneViewMouseMessage(mouseMessage);
|
||||
}
|
||||
|
||||
private void CatchHotControl()
|
||||
{
|
||||
int controlId = GUIUtility.GetControlID(this.GetHashCode(), FocusType.Passive);
|
||||
if (Event.current.type == EventType.MouseDown)
|
||||
{
|
||||
if (Event.current.button == 0)
|
||||
{
|
||||
GUIUtility.hotControl = controlId;
|
||||
//OnMouseDown(Event.current);
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
if (GUIUtility.hotControl == controlId)
|
||||
{
|
||||
//OnMouseUp(Event.current);
|
||||
//Return the hot control back to Unity, use the default
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.KeyDown)
|
||||
{
|
||||
//OnKeyDown(Event.current);
|
||||
}
|
||||
}
|
||||
|
||||
public static float DistanceMouseToSpline(Vector2 mousePosition, params Vector3[] splinePoint)
|
||||
{
|
||||
float d = float.MaxValue;
|
||||
for (int i = 0; i < splinePoint.Length - 1; ++i)
|
||||
{
|
||||
float d1 = HandleUtility.DistancePointToLineSegment(
|
||||
mousePosition,
|
||||
HandleUtility.WorldToGUIPoint(splinePoint[i]),
|
||||
HandleUtility.WorldToGUIPoint(splinePoint[i + 1]));
|
||||
if (d1 < d)
|
||||
d = d1;
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
public static float DistanceMouseToPoint(Vector2 mousePosition, Vector3 worldPoint)
|
||||
{
|
||||
float d = Vector2.Distance(
|
||||
mousePosition,
|
||||
HandleUtility.WorldToGUIPoint(worldPoint));
|
||||
return d;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98ebbf81516ce744095876c548d6dbe4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.Poseidon;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
//[CreateAssetMenu(menuName = "Poseidon/Spline Tool Config")]
|
||||
public class PSplineToolConfig : ScriptableObject
|
||||
{
|
||||
private static PSplineToolConfig instance;
|
||||
public static PSplineToolConfig Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance==null)
|
||||
{
|
||||
instance = Resources.Load<PSplineToolConfig>("SplineToolConfig");
|
||||
if (instance==null)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<PSplineToolConfig>();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int raycastLayer;
|
||||
public int RaycastLayer
|
||||
{
|
||||
get
|
||||
{
|
||||
return raycastLayer;
|
||||
}
|
||||
set
|
||||
{
|
||||
raycastLayer = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float yOffset;
|
||||
public float YOffset
|
||||
{
|
||||
get
|
||||
{
|
||||
return yOffset;
|
||||
}
|
||||
set
|
||||
{
|
||||
yOffset = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private bool autoTangent;
|
||||
public bool AutoTangent
|
||||
{
|
||||
get
|
||||
{
|
||||
return autoTangent;
|
||||
}
|
||||
set
|
||||
{
|
||||
autoTangent = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86645776c4e1905439fdfc64c6cc0794
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,135 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
public class PTilesEditingGUIDrawer
|
||||
{
|
||||
private PWater water;
|
||||
|
||||
public PTilesEditingGUIDrawer(PWater water)
|
||||
{
|
||||
this.water = water;
|
||||
}
|
||||
|
||||
public void Draw()
|
||||
{
|
||||
if (Event.current == null)
|
||||
return;
|
||||
DrawExistingTiles();
|
||||
HandleAddRemoveTiles();
|
||||
CatchHotControl();
|
||||
}
|
||||
|
||||
private void DrawExistingTiles()
|
||||
{
|
||||
for (int i = 0; i < water.TileIndices.Count; ++i)
|
||||
{
|
||||
PIndex2D index = water.TileIndices[i];
|
||||
Vector3 rectCenter = water.transform.TransformPoint(new Vector3(
|
||||
(index.X + 0.5f) * water.TileSize.x,
|
||||
0,
|
||||
(index.Z + 0.5f) * water.TileSize.y));
|
||||
Vector3 rectSize = water.transform.TransformVector(new Vector3(
|
||||
water.TileSize.x,
|
||||
0,
|
||||
water.TileSize.y));
|
||||
|
||||
Handles.color = new Color(1, 1, 1, 0.05f);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.Greater;
|
||||
Handles.DrawWireCube(rectCenter, rectSize);
|
||||
|
||||
Handles.color = new Color(1, 1, 1, 1);
|
||||
Handles.zTest = UnityEngine.Rendering.CompareFunction.LessEqual;
|
||||
Handles.DrawWireCube(rectCenter, rectSize);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAddRemoveTiles()
|
||||
{
|
||||
Plane plane = new Plane(Vector3.up, water.transform.position);
|
||||
Ray r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
|
||||
float distance = -1;
|
||||
if (plane.Raycast(r, out distance))
|
||||
{
|
||||
Vector3 hitWorldPos = r.origin + r.direction * distance;
|
||||
Vector3 hitLocalPos = water.transform.InverseTransformPoint(hitWorldPos);
|
||||
PIndex2D index = new PIndex2D(
|
||||
Mathf.FloorToInt(hitLocalPos.x / water.TileSize.x),
|
||||
Mathf.FloorToInt(hitLocalPos.z / water.TileSize.y));
|
||||
|
||||
Vector3 rectCenter = water.transform.TransformPoint(new Vector3(
|
||||
(index.X + 0.5f) * water.TileSize.x,
|
||||
hitLocalPos.y,
|
||||
(index.Z + 0.5f) * water.TileSize.y));
|
||||
Vector3 rectSize = water.transform.TransformVector(new Vector3(
|
||||
water.TileSize.x,
|
||||
0,
|
||||
water.TileSize.y));
|
||||
|
||||
if (Event.current.type == EventType.MouseDrag || Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
if (Event.current.button != 0)
|
||||
return;
|
||||
if (Event.current.control)
|
||||
{
|
||||
water.TileIndices.Remove(index);
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
else if (Event.current.shift)
|
||||
{
|
||||
if (!water.TileIndices.Contains(index))
|
||||
{
|
||||
water.TileIndices.Add(index);
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
}
|
||||
PUtilities.MarkCurrentSceneDirty();
|
||||
EditorUtility.SetDirty(water);
|
||||
}
|
||||
|
||||
Handles.color = Handles.selectedColor;
|
||||
Handles.DrawWireCube(rectCenter, rectSize);
|
||||
|
||||
string s = string.Format(
|
||||
"{0}" +
|
||||
"{1}" +
|
||||
"{2}",
|
||||
index.ToString(),
|
||||
"\nShift+Click to pin, Ctrl+Click to unpin water planes.",
|
||||
"\nClick End Editing Tiles when done.");
|
||||
|
||||
GUIContent mouseMessage = new GUIContent(s);
|
||||
PEditorCommon.SceneViewMouseMessage(mouseMessage);
|
||||
}
|
||||
}
|
||||
|
||||
private void CatchHotControl()
|
||||
{
|
||||
int controlId = GUIUtility.GetControlID(this.GetHashCode(), FocusType.Passive);
|
||||
if (Event.current.type == EventType.MouseDown)
|
||||
{
|
||||
if (Event.current.button == 0)
|
||||
{
|
||||
GUIUtility.hotControl = controlId;
|
||||
//OnMouseDown(Event.current);
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
if (GUIUtility.hotControl == controlId)
|
||||
{
|
||||
//OnMouseUp(Event.current);
|
||||
//Return the hot control back to Unity, use the default
|
||||
GUIUtility.hotControl = 0;
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.KeyDown)
|
||||
{
|
||||
//OnKeyDown(Event.current);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e796169c8ef1d6147bd2556326c1f222
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,958 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using Pinwheel.Poseidon.FX;
|
||||
using UnityEngine.Rendering;
|
||||
#if TEXTURE_GRAPH
|
||||
using Pinwheel.TextureGraph;
|
||||
#endif
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
[CustomEditor(typeof(PWater))]
|
||||
public class PWaterInspector : Editor
|
||||
{
|
||||
private PWater water;
|
||||
private PWaterProfile profile;
|
||||
private bool willDrawDebugGUI = false;
|
||||
|
||||
private SerializedObject so;
|
||||
private SerializedProperty reflectionLayersSO;
|
||||
private SerializedProperty refractionLayersSO;
|
||||
|
||||
private readonly int[] renderTextureSizes = new int[] { 128, 256, 512, 1024, 2048 };
|
||||
private readonly string[] renderTextureSizeLabels = new string[] { "128", "256", "512", "1024", "2048*" };
|
||||
|
||||
private readonly int[] meshTypes = new int[]
|
||||
{
|
||||
(int)PWaterMeshType.TileablePlane,
|
||||
(int)PWaterMeshType.Area,
|
||||
(int)PWaterMeshType.Spline,
|
||||
(int)PWaterMeshType.CustomMesh
|
||||
};
|
||||
private readonly string[] meshTypeLabels = new string[]
|
||||
{
|
||||
"Tilealbe Plane",
|
||||
"Area (Experimental)",
|
||||
"Spline (Experimental)",
|
||||
"Custom (Experimental)"
|
||||
};
|
||||
|
||||
private bool isEditingTileIndices = false;
|
||||
private bool isEditingAreaMesh = false;
|
||||
private bool isEditingSplineMesh = false;
|
||||
|
||||
private PTilesEditingGUIDrawer tileEditingGUIDrawer;
|
||||
private PAreaEditingGUIDrawer areaEditingGUIDrawer;
|
||||
private PSplineEditingGUIDrawer splineEditingGUIDrawer;
|
||||
|
||||
private static Mesh quadMesh;
|
||||
private static Mesh QuadMesh
|
||||
{
|
||||
get
|
||||
{
|
||||
if (quadMesh == null)
|
||||
{
|
||||
quadMesh = Resources.GetBuiltinResource<Mesh>("Quad.fbx");
|
||||
}
|
||||
return quadMesh;
|
||||
}
|
||||
}
|
||||
|
||||
private static Material maskVisualizerMaterial;
|
||||
private static Material MaskVisualizerMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (maskVisualizerMaterial == null)
|
||||
{
|
||||
maskVisualizerMaterial = new Material(Shader.Find("Hidden/Poseidon/WaveMaskVisualizer"));
|
||||
}
|
||||
return maskVisualizerMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
private enum PWaveMaskVisualizationMode
|
||||
{
|
||||
None,
|
||||
//Flow,
|
||||
Crest,
|
||||
Height
|
||||
}
|
||||
|
||||
private PWaveMaskVisualizationMode waveMaskVisMode;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
LoadPrefs();
|
||||
water = target as PWater;
|
||||
if (water.Profile != null)
|
||||
{
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
|
||||
tileEditingGUIDrawer = new PTilesEditingGUIDrawer(water);
|
||||
areaEditingGUIDrawer = new PAreaEditingGUIDrawer(water);
|
||||
splineEditingGUIDrawer = new PSplineEditingGUIDrawer(water);
|
||||
|
||||
SceneView.duringSceneGui += DuringSceneGUI;
|
||||
Camera.onPreCull += OnRenderCamera;
|
||||
RenderPipelineManager.beginCameraRendering += OnRenderCameraSRP;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SavePrefs();
|
||||
isEditingTileIndices = false;
|
||||
if (isEditingAreaMesh)
|
||||
{
|
||||
isEditingAreaMesh = false;
|
||||
water.GenerateAreaMesh();
|
||||
}
|
||||
if (isEditingSplineMesh)
|
||||
{
|
||||
isEditingSplineMesh = false;
|
||||
water.GenerateSplineMesh();
|
||||
}
|
||||
|
||||
SceneView.duringSceneGui -= DuringSceneGUI;
|
||||
Camera.onPreCull -= OnRenderCamera;
|
||||
RenderPipelineManager.beginCameraRendering -= OnRenderCameraSRP;
|
||||
}
|
||||
|
||||
private void LoadPrefs()
|
||||
{
|
||||
waveMaskVisMode = (PWaveMaskVisualizationMode)SessionState.GetInt("poseidon-wave-mask-vis-mode", 0);
|
||||
}
|
||||
|
||||
private void SavePrefs()
|
||||
{
|
||||
SessionState.SetInt("poseidon-wave-mask-vis-mode", (int)waveMaskVisMode);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
if (water.transform.rotation != Quaternion.identity)
|
||||
{
|
||||
string warning = "The water object is designed to work without rotation. Some features may not work correctly.";
|
||||
EditorGUILayout.LabelField(warning, PEditorCommon.WarningLabel);
|
||||
}
|
||||
|
||||
water.Profile = PEditorCommon.ScriptableObjectField<PWaterProfile>("Profile", water.Profile);
|
||||
profile = water.Profile;
|
||||
if (water.Profile == null)
|
||||
return;
|
||||
so = new SerializedObject(profile);
|
||||
reflectionLayersSO = so.FindProperty("reflectionLayers");
|
||||
refractionLayersSO = so.FindProperty("refractionLayers");
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawMeshSettingsGUI();
|
||||
DrawRenderingSettingsGUI();
|
||||
DrawTimeSettingsGUI();
|
||||
DrawColorsSettingsGUI();
|
||||
DrawFresnelSettingsGUI();
|
||||
DrawRippleSettingsGUI();
|
||||
DrawWaveSettingsGUI();
|
||||
DrawLightAbsorbtionSettingsGUI();
|
||||
DrawFoamSettingsGUI();
|
||||
DrawReflectionSettingsGUI();
|
||||
DrawRefractionSettingsGUI();
|
||||
DrawCausticSettingsGUI();
|
||||
#if AURA_IN_PROJECT
|
||||
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
|
||||
{
|
||||
DrawAuraIntegrationSettingsGUI();
|
||||
}
|
||||
#endif
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorUtility.SetDirty(water);
|
||||
EditorUtility.SetDirty(profile);
|
||||
water.UpdateMaterial();
|
||||
}
|
||||
|
||||
DrawEffectsGUI();
|
||||
if (willDrawDebugGUI)
|
||||
DrawDebugGUI();
|
||||
|
||||
if (so != null)
|
||||
{
|
||||
so.Dispose();
|
||||
}
|
||||
|
||||
if (reflectionLayersSO != null)
|
||||
{
|
||||
reflectionLayersSO.Dispose();
|
||||
}
|
||||
|
||||
if (refractionLayersSO != null)
|
||||
{
|
||||
refractionLayersSO.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEffectsGUI()
|
||||
{
|
||||
PWaterFX fx = water.GetComponent<PWaterFX>();
|
||||
if (fx != null)
|
||||
return;
|
||||
|
||||
string label = "Effects";
|
||||
string id = "effects" + water.GetInstanceID();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
GUI.enabled = true;
|
||||
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
|
||||
{
|
||||
bool isStackV2Installed = false;
|
||||
#if UNITY_POST_PROCESSING_STACK_V2
|
||||
isStackV2Installed = true;
|
||||
#endif
|
||||
if (!isStackV2Installed)
|
||||
{
|
||||
EditorGUILayout.LabelField("Water effect need the Post Processing Stack V2 to work. Please install it using the Package Manager", PEditorCommon.WordWrapItalicLabel);
|
||||
}
|
||||
GUI.enabled = isStackV2Installed;
|
||||
}
|
||||
if (GUILayout.Button("Add Effects"))
|
||||
{
|
||||
fx = water.gameObject.AddComponent<PWaterFX>();
|
||||
fx.Water = water;
|
||||
}
|
||||
GUI.enabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawMeshSettingsGUI()
|
||||
{
|
||||
string label = "Mesh";
|
||||
string id = "water-profile-mesh";
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddItem(
|
||||
new GUIContent("Generate"),
|
||||
false,
|
||||
() => { water.GenerateMesh(); });
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
if (water.MeshType == PWaterMeshType.TileablePlane)
|
||||
{
|
||||
DrawTilableMeshGUI();
|
||||
}
|
||||
else if (water.MeshType == PWaterMeshType.Area)
|
||||
{
|
||||
DrawAreaMeshGUI();
|
||||
}
|
||||
else if (water.MeshType == PWaterMeshType.Spline)
|
||||
{
|
||||
DrawSplineMeshGUI();
|
||||
}
|
||||
else if (water.MeshType == PWaterMeshType.CustomMesh)
|
||||
{
|
||||
DrawCustomMeshGUI();
|
||||
}
|
||||
}, menu);
|
||||
}
|
||||
|
||||
private void DrawTilableMeshGUI()
|
||||
{
|
||||
if (!isEditingTileIndices)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
//water.MeshType = (PWaterMeshType)EditorGUILayout.EnumPopup("Mesh Type", water.MeshType);
|
||||
water.MeshType = (PWaterMeshType)EditorGUILayout.IntPopup("Mesh Type", (int)water.MeshType, meshTypeLabels, meshTypes);
|
||||
water.PlanePattern = (PPlaneMeshPattern)EditorGUILayout.EnumPopup("Pattern", water.PlanePattern);
|
||||
water.MeshResolution = EditorGUILayout.DelayedIntField("Resolution", water.MeshResolution);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.GenerateMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
water.MeshNoise = EditorGUILayout.FloatField("Noise", water.MeshNoise);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
water.TileSize = PEditorCommon.InlineVector2Field("Tile Size", water.TileSize);
|
||||
water.TilesFollowMainCamera = EditorGUILayout.Toggle("Follow Main Camera", water.TilesFollowMainCamera);
|
||||
SerializedObject so = new SerializedObject(water);
|
||||
SerializedProperty sp = so.FindProperty("tileIndices");
|
||||
|
||||
if (sp != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(sp, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
sp.Dispose();
|
||||
so.Dispose();
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
}
|
||||
|
||||
if (!isEditingTileIndices)
|
||||
{
|
||||
if (GUILayout.Button("Edit Tiles"))
|
||||
{
|
||||
isEditingTileIndices = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField("Edit water tiles in Scene View.", PEditorCommon.WordWrapItalicLabel);
|
||||
if (GUILayout.Button("End Editing Tiles"))
|
||||
{
|
||||
isEditingTileIndices = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAreaMeshGUI()
|
||||
{
|
||||
if (!isEditingAreaMesh)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
//water.MeshType = (PWaterMeshType)EditorGUILayout.EnumPopup("Mesh Type", water.MeshType);
|
||||
water.MeshType = (PWaterMeshType)EditorGUILayout.IntPopup("Mesh Type", (int)water.MeshType, meshTypeLabels, meshTypes);
|
||||
water.MeshResolution = EditorGUILayout.DelayedIntField("Resolution", water.MeshResolution);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.GenerateMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
water.MeshNoise = EditorGUILayout.FloatField("Noise", water.MeshNoise);
|
||||
|
||||
SerializedObject so = new SerializedObject(water);
|
||||
SerializedProperty sp = so.FindProperty("areaMeshAnchors");
|
||||
|
||||
if (sp != null)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
EditorGUILayout.PropertyField(sp, true);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
so.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
sp.Dispose();
|
||||
so.Dispose();
|
||||
}
|
||||
|
||||
if (!isEditingAreaMesh)
|
||||
{
|
||||
if (GUILayout.Button("Edit Area"))
|
||||
{
|
||||
isEditingAreaMesh = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GUILayout.Button("End Editing Area"))
|
||||
{
|
||||
isEditingAreaMesh = false;
|
||||
water.GenerateAreaMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSplineMeshGUI()
|
||||
{
|
||||
if (!isEditingSplineMesh)
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
//water.MeshType = (PWaterMeshType)EditorGUILayout.EnumPopup("Mesh Type", water.MeshType);
|
||||
water.MeshType = (PWaterMeshType)EditorGUILayout.IntPopup("Mesh Type", (int)water.MeshType, meshTypeLabels, meshTypes);
|
||||
water.SplineResolutionX = EditorGUILayout.DelayedIntField("Resolution X", water.SplineResolutionX);
|
||||
water.SplineResolutionY = EditorGUILayout.DelayedIntField("Resolution Y", water.SplineResolutionY);
|
||||
water.SplineWidth = EditorGUILayout.DelayedFloatField("Width", water.SplineWidth);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.GenerateMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
//water.MeshNoise = EditorGUILayout.FloatField("Noise", water.MeshNoise);
|
||||
}
|
||||
|
||||
if (!isEditingSplineMesh)
|
||||
{
|
||||
if (GUILayout.Button("Edit Spline"))
|
||||
{
|
||||
isEditingSplineMesh = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PSplineToolConfig.Instance.RaycastLayer = EditorGUILayout.LayerField("Raycast Layer", PSplineToolConfig.Instance.RaycastLayer);
|
||||
PSplineToolConfig.Instance.YOffset = EditorGUILayout.FloatField("Y Offset", PSplineToolConfig.Instance.YOffset);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
PSplineToolConfig.Instance.AutoTangent = EditorGUILayout.Toggle("Auto Tangent", PSplineToolConfig.Instance.AutoTangent);
|
||||
if (EditorGUI.EndChangeCheck() && PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
water.Spline.SmoothTangents();
|
||||
water.GenerateSplineMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
EditorUtility.SetDirty(PSplineToolConfig.Instance);
|
||||
DrawSelectedAnchorGUI();
|
||||
DrawSelectedSegmentGUI();
|
||||
|
||||
if (GUILayout.Button("Smooth Tangents"))
|
||||
{
|
||||
water.Spline.SmoothTangents();
|
||||
water.GenerateSplineMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
if (GUILayout.Button("Pivot To Spline Center"))
|
||||
{
|
||||
PSplineUtilities.WaterPivotToSplineCenter(water);
|
||||
water.GenerateSplineMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
if (GUILayout.Button("End Editing Spline"))
|
||||
{
|
||||
isEditingSplineMesh = false;
|
||||
water.GenerateSplineMesh();
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawSelectedAnchorGUI()
|
||||
{
|
||||
int anchorIndex = splineEditingGUIDrawer.selectedAnchorIndex;
|
||||
if (anchorIndex < 0 ||
|
||||
anchorIndex >= water.Spline.Anchors.Count)
|
||||
return;
|
||||
string label = "Selected Anchor";
|
||||
string id = "poseidon-selected-anchor";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
EditorGUI.indentLevel -= 1;
|
||||
PSplineAnchor a = water.Spline.Anchors[anchorIndex];
|
||||
EditorGUI.BeginChangeCheck();
|
||||
a.Position = PEditorCommon.InlineVector3Field("Position", a.Position);
|
||||
a.Rotation = Quaternion.Euler(PEditorCommon.InlineVector3Field("Rotation", a.Rotation.eulerAngles));
|
||||
a.Scale = PEditorCommon.InlineVector3Field("Scale", a.Scale);
|
||||
water.Spline.Anchors[anchorIndex] = a;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (PSplineToolConfig.Instance.AutoTangent)
|
||||
{
|
||||
int[] segmentIndices = water.Spline.SmoothTangents(anchorIndex);
|
||||
water.GenerateSplineMeshAtSegments(segmentIndices);
|
||||
}
|
||||
else
|
||||
{
|
||||
List<int> segmentIndices = water.Spline.FindSegments(anchorIndex);
|
||||
water.GenerateSplineMeshAtSegments(segmentIndices);
|
||||
}
|
||||
}
|
||||
EditorGUI.indentLevel += 1;
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawSelectedSegmentGUI()
|
||||
{
|
||||
int segmentIndex = splineEditingGUIDrawer.selectedSegmentIndex;
|
||||
if (segmentIndex < 0 ||
|
||||
segmentIndex >= water.Spline.Anchors.Count)
|
||||
return;
|
||||
string label = "Selected Segment";
|
||||
string id = "poseidon-selected-segment";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
EditorGUI.indentLevel -= 1;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
PSplineSegment s = water.Spline.Segments[segmentIndex];
|
||||
GUI.enabled = !PSplineToolConfig.Instance.AutoTangent;
|
||||
s.StartTangent = PEditorCommon.InlineVector3Field("Start Tangent", s.StartTangent);
|
||||
s.EndTangent = PEditorCommon.InlineVector3Field("End Tangent", s.EndTangent);
|
||||
GUI.enabled = true;
|
||||
s.ResolutionMultiplierY = EditorGUILayout.Slider("Resolution Multiplier Y", s.ResolutionMultiplierY, 0f, 2f);
|
||||
water.Spline.Segments[segmentIndex] = s;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
water.GenerateSplineMeshAtSegment(segmentIndex);
|
||||
}
|
||||
EditorGUI.indentLevel += 1;
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawCustomMeshGUI()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
//water.MeshType = (PWaterMeshType)EditorGUILayout.EnumPopup("Mesh Type", water.MeshType);
|
||||
water.MeshType = (PWaterMeshType)EditorGUILayout.IntPopup("Mesh Type", (int)water.MeshType, meshTypeLabels, meshTypes);
|
||||
water.SourceMesh = EditorGUILayout.ObjectField("Source Mesh", water.SourceMesh, typeof(Mesh), false) as Mesh;
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (water.SourceMesh != null)
|
||||
{
|
||||
water.GenerateMesh();
|
||||
}
|
||||
water.ReCalculateBounds();
|
||||
}
|
||||
water.MeshNoise = EditorGUILayout.FloatField("Noise", water.MeshNoise);
|
||||
}
|
||||
|
||||
private void DrawRenderingSettingsGUI()
|
||||
{
|
||||
string label = "Rendering";
|
||||
string id = "water-profile-general";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUILayout.ObjectField("Material", water.MaterialToRender, typeof(Material), false);
|
||||
if (water.MeshType == PWaterMeshType.TileablePlane && water.ShouldRenderBackface)
|
||||
{
|
||||
EditorGUILayout.ObjectField("Material Back Face", water.MaterialBackFace, typeof(Material), false);
|
||||
}
|
||||
GUI.enabled = true;
|
||||
profile.RenderQueueIndex = EditorGUILayout.IntField("Queue Index", profile.RenderQueueIndex);
|
||||
|
||||
profile.LightingModel = (PLightingModel)EditorGUILayout.EnumPopup("Light Model", profile.LightingModel);
|
||||
profile.UseFlatLighting = EditorGUILayout.Toggle("Flat Lighting", profile.UseFlatLighting);
|
||||
if (water.MeshType == PWaterMeshType.TileablePlane)
|
||||
{
|
||||
water.ShouldRenderBackface = EditorGUILayout.Toggle("Render Back Face", water.ShouldRenderBackface);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawTimeSettingsGUI()
|
||||
{
|
||||
string label = "Time";
|
||||
string id = "water-time";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
water.TimeMode = (PTimeMode)EditorGUILayout.EnumPopup("Time Mode", water.TimeMode);
|
||||
if (water.TimeMode == PTimeMode.Auto)
|
||||
{
|
||||
EditorGUILayout.LabelField("Time", water.GetTimeParam().ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
water.ManualTimeSeconds = EditorGUILayout.FloatField("Time", (float)water.ManualTimeSeconds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawColorsSettingsGUI()
|
||||
{
|
||||
string label = "Colors";
|
||||
string id = "water-profile-colors";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.Color = EditorGUILayout.ColorField("Color", profile.Color);
|
||||
if (profile.EnableLightAbsorption)
|
||||
{
|
||||
profile.DepthColor = EditorGUILayout.ColorField("Depth Color", profile.DepthColor);
|
||||
}
|
||||
if (profile.LightingModel == PLightingModel.PhysicalBased || profile.LightingModel == PLightingModel.BlinnPhong)
|
||||
{
|
||||
//instance.SpecColor = EditorGUILayout.ColorField("Specular Color", instance.SpecColor);
|
||||
profile.SpecColor = EditorGUILayout.ColorField(new GUIContent("Specular Color"), profile.SpecColor, true, false, true);
|
||||
profile.Smoothness = EditorGUILayout.Slider("Smoothness", profile.Smoothness, 0f, 1f);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawFresnelSettingsGUI()
|
||||
{
|
||||
string label = "Fresnel";
|
||||
string id = "water-profile-fresnel";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.FresnelStrength = EditorGUILayout.Slider("Strength", profile.FresnelStrength, 0f, 10f);
|
||||
profile.FresnelBias = EditorGUILayout.Slider("Bias", profile.FresnelBias, 0f, 1f);
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawLightAbsorbtionSettingsGUI()
|
||||
{
|
||||
string label = "Light Absorption";
|
||||
string id = "water-profile-absorption";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.EnableLightAbsorption = EditorGUILayout.Toggle("Enable", profile.EnableLightAbsorption);
|
||||
if (profile.EnableLightAbsorption)
|
||||
{
|
||||
profile.DepthColor = EditorGUILayout.ColorField("Depth Color", profile.DepthColor);
|
||||
profile.MaxDepth = EditorGUILayout.FloatField("Max Depth", profile.MaxDepth);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawFoamSettingsGUI()
|
||||
{
|
||||
string label = "Foam";
|
||||
string id = "water-profile-foam";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.EnableFoam = EditorGUILayout.Toggle("Enable", profile.EnableFoam);
|
||||
if (profile.EnableFoam)
|
||||
{
|
||||
profile.EnableFoamHQ = EditorGUILayout.Toggle("High Quality", profile.EnableFoamHQ);
|
||||
if (profile.EnableFoamHQ)
|
||||
{
|
||||
profile.FoamNoiseScaleHQ = EditorGUILayout.FloatField("Scale", profile.FoamNoiseScaleHQ);
|
||||
profile.FoamNoiseSpeedHQ = EditorGUILayout.FloatField("Speed", profile.FoamNoiseSpeedHQ);
|
||||
}
|
||||
profile.FoamColor = EditorGUILayout.ColorField(new GUIContent("Color"), profile.FoamColor, true, true, true);
|
||||
|
||||
PEditorCommon.Header("Shoreline");
|
||||
profile.FoamDistance = EditorGUILayout.FloatField("Distance", profile.FoamDistance);
|
||||
profile.ShorelineFoamStrength = EditorGUILayout.Slider("Strength", profile.ShorelineFoamStrength, 0f, 1f);
|
||||
|
||||
if (profile.EnableWave)
|
||||
{
|
||||
PEditorCommon.Header("Crest");
|
||||
profile.CrestMaxDepth = EditorGUILayout.FloatField("Max Depth", profile.CrestMaxDepth);
|
||||
profile.CrestFoamStrength = EditorGUILayout.Slider("Strength", profile.CrestFoamStrength, 0f, 1f);
|
||||
}
|
||||
|
||||
if (water.MeshType == PWaterMeshType.Spline)
|
||||
{
|
||||
PEditorCommon.Header("Slope");
|
||||
profile.SlopeFoamDistance = EditorGUILayout.FloatField("Distance", profile.SlopeFoamDistance);
|
||||
profile.SlopeFoamFlowSpeed = EditorGUILayout.FloatField("Flow Speed", profile.SlopeFoamFlowSpeed);
|
||||
profile.SlopeFoamStrength = EditorGUILayout.Slider("Strength", profile.SlopeFoamStrength, 0f, 1f);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawRippleSettingsGUI()
|
||||
{
|
||||
string label = "Ripple";
|
||||
string id = "water-profile-ripple";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.RippleHeight = EditorGUILayout.Slider("Height", profile.RippleHeight, 0f, 1f);
|
||||
profile.RippleNoiseScale = EditorGUILayout.FloatField("Scale", profile.RippleNoiseScale);
|
||||
profile.RippleSpeed = EditorGUILayout.FloatField("Speed", profile.RippleSpeed);
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawWaveSettingsGUI()
|
||||
{
|
||||
string label = "Wave";
|
||||
string id = "water-profile-wave";
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
profile.EnableWave = EditorGUILayout.Toggle("Enable", profile.EnableWave);
|
||||
if (profile.EnableWave)
|
||||
{
|
||||
profile.WaveDirection = EditorGUILayout.Slider("Direction", profile.WaveDirection, 0f, 360f);
|
||||
profile.WaveSpeed = EditorGUILayout.FloatField("Speed", profile.WaveSpeed);
|
||||
profile.WaveHeight = EditorGUILayout.FloatField("Height", profile.WaveHeight);
|
||||
profile.WaveLength = EditorGUILayout.FloatField("Length", profile.WaveLength);
|
||||
profile.WaveSteepness = EditorGUILayout.Slider("Steepness", profile.WaveSteepness, 0f, 1f);
|
||||
profile.WaveDeform = EditorGUILayout.Slider("Deform", profile.WaveDeform, 0f, 1f);
|
||||
|
||||
water.UseWaveMask = EditorGUILayout.Toggle("Use Mask", water.UseWaveMask);
|
||||
if (water.UseWaveMask)
|
||||
{
|
||||
waveMaskVisMode = (PWaveMaskVisualizationMode)EditorGUILayout.EnumPopup("Visualization", waveMaskVisMode);
|
||||
EditorGUIUtility.wideMode = true;
|
||||
water.WaveMaskBounds = EditorGUILayout.RectField("Bounds", water.WaveMaskBounds);
|
||||
EditorGUIUtility.wideMode = false;
|
||||
//#if TEXTURE_GRAPH
|
||||
// water.UseEmbeddedWaveMask = EditorGUILayout.Toggle("Use Embedded Mask", water.UseEmbeddedWaveMask);
|
||||
// if (water.UseEmbeddedWaveMask)
|
||||
// {
|
||||
// water.TextureGraphAsset = EditorGUILayout.ObjectField("Texture Graph Asset", water.TextureGraphAsset, typeof(TGraph), false) as TGraph;
|
||||
// GUI.enabled = false;
|
||||
// PEditorCommon.InlineTextureField("Mask", water.EmbeddedWaveMask, -1);
|
||||
// GUI.enabled = water.TextureGraphAsset != null;
|
||||
// if (GUILayout.Button("Embed Mask"))
|
||||
// {
|
||||
// water.EmbedWaveMask();
|
||||
// }
|
||||
// GUI.enabled = true;
|
||||
// }
|
||||
// else
|
||||
//#endif
|
||||
{
|
||||
water.WaveMask = PEditorCommon.InlineTexture2DField("Mask", water.WaveMask, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawReflectionSettingsGUI()
|
||||
{
|
||||
if (water.MeshType == PWaterMeshType.Spline)
|
||||
return;
|
||||
|
||||
bool stereoEnable = false;
|
||||
if (Camera.main != null)
|
||||
{
|
||||
stereoEnable = Camera.main.stereoEnabled;
|
||||
}
|
||||
|
||||
string label = "Reflection" + (stereoEnable ? " (Not support for VR)" : "");
|
||||
string id = "water-profile-reflection";
|
||||
|
||||
GUI.enabled = !stereoEnable;
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
profile.EnableReflection = EditorGUILayout.Toggle("Enable", profile.EnableReflection);
|
||||
if (profile.EnableReflection)
|
||||
{
|
||||
profile.ReflectCustomSkybox = EditorGUILayout.Toggle("Custom Skybox", profile.ReflectCustomSkybox);
|
||||
profile.EnableReflectionPixelLight = EditorGUILayout.Toggle("Pixel Light", profile.EnableReflectionPixelLight);
|
||||
profile.ReflectionClipPlaneOffset = EditorGUILayout.FloatField("Clip Plane Offset", profile.ReflectionClipPlaneOffset);
|
||||
|
||||
if (reflectionLayersSO != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(reflectionLayersSO);
|
||||
}
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
profile.ReflectionTextureResolution = EditorGUILayout.IntPopup("Resolution", profile.ReflectionTextureResolution, renderTextureSizeLabels, renderTextureSizes);
|
||||
profile.ReflectionDistortionStrength = EditorGUILayout.FloatField("Distortion", profile.ReflectionDistortionStrength);
|
||||
}
|
||||
});
|
||||
GUI.enabled = true;
|
||||
}
|
||||
|
||||
private void DrawRefractionSettingsGUI()
|
||||
{
|
||||
string label = "Refraction";
|
||||
string id = "water-profile-refraction";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
if (water.MeshType != PWaterMeshType.Spline)
|
||||
{
|
||||
profile.EnableRefraction = EditorGUILayout.Toggle("Enable", profile.EnableRefraction);
|
||||
}
|
||||
if (profile.EnableRefraction || water.MeshType == PWaterMeshType.Spline)
|
||||
{
|
||||
profile.RefractionDistortionStrength = EditorGUILayout.FloatField("Distortion", profile.RefractionDistortionStrength);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawCausticSettingsGUI()
|
||||
{
|
||||
string label = "Caustic";
|
||||
string id = "water-profile-caustic";
|
||||
|
||||
PEditorCommon.Foldout(label, true, id, () =>
|
||||
{
|
||||
bool valid = (profile.EnableRefraction || water.MeshType == PWaterMeshType.Spline);
|
||||
if (!valid)
|
||||
{
|
||||
EditorGUILayout.LabelField("Requires Refraction.", PEditorCommon.WordWrapItalicLabel);
|
||||
profile.EnableCaustic = false;
|
||||
}
|
||||
|
||||
GUI.enabled = valid;
|
||||
profile.EnableCaustic = EditorGUILayout.Toggle("Enable", profile.EnableCaustic);
|
||||
if (profile.EnableCaustic)
|
||||
{
|
||||
profile.CausticTexture = PEditorCommon.InlineTextureField("Texture", profile.CausticTexture, -1);
|
||||
profile.CausticSize = EditorGUILayout.FloatField("Size", profile.CausticSize);
|
||||
profile.CausticStrength = EditorGUILayout.Slider("Strength", profile.CausticStrength, 0f, 5f);
|
||||
profile.CausticDistortionStrength = EditorGUILayout.FloatField("Distortion", profile.CausticDistortionStrength);
|
||||
}
|
||||
GUI.enabled = true;
|
||||
});
|
||||
}
|
||||
|
||||
#if AURA_IN_PROJECT
|
||||
private void DrawAuraIntegrationSettingsGUI()
|
||||
{
|
||||
string label = "Aura 2 Integration";
|
||||
string id = "water-profile-aura-integration";
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
profile.ApplyAuraFog = EditorGUILayout.Toggle("Apply Fog", profile.ApplyAuraFog);
|
||||
profile.ApplyAuraLighting = EditorGUILayout.Toggle("Apply Lighting", profile.ApplyAuraLighting);
|
||||
if (profile.ApplyAuraLighting)
|
||||
{
|
||||
profile.AuraLightingFactor = EditorGUILayout.FloatField("Lighting Factor", profile.AuraLightingFactor);
|
||||
}
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
||||
private void DuringSceneGUI(SceneView sv)
|
||||
{
|
||||
Tools.hidden = isEditingTileIndices || isEditingAreaMesh || isEditingSplineMesh;
|
||||
if (water.MeshType == PWaterMeshType.TileablePlane && isEditingTileIndices)
|
||||
{
|
||||
DrawEditingTilesGUI();
|
||||
}
|
||||
|
||||
if (water.MeshType == PWaterMeshType.Area && isEditingAreaMesh)
|
||||
{
|
||||
DrawEditingAreaMeshGUI();
|
||||
}
|
||||
|
||||
if (water.MeshType == PWaterMeshType.Spline && isEditingSplineMesh)
|
||||
{
|
||||
DrawEditingSplineGUI();
|
||||
}
|
||||
|
||||
if (isEditingTileIndices || isEditingAreaMesh || isEditingSplineMesh)
|
||||
{
|
||||
DrawBounds();
|
||||
}
|
||||
|
||||
bool isWaveSectionExpanded = PEditorCommon.IsFoldoutExpanded("water-profile-wave");
|
||||
if (isWaveSectionExpanded && water.UseWaveMask)
|
||||
{
|
||||
DrawWaveMaskBounds();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawEditingTilesGUI()
|
||||
{
|
||||
tileEditingGUIDrawer.Draw();
|
||||
}
|
||||
|
||||
private void DrawEditingAreaMeshGUI()
|
||||
{
|
||||
areaEditingGUIDrawer.Draw();
|
||||
}
|
||||
|
||||
private void DrawEditingSplineGUI()
|
||||
{
|
||||
splineEditingGUIDrawer.Draw();
|
||||
}
|
||||
|
||||
private void DrawBounds()
|
||||
{
|
||||
if (Event.current == null)
|
||||
return;
|
||||
if (water.Profile == null)
|
||||
return;
|
||||
|
||||
Vector3 center = water.transform.TransformPoint(water.Bounds.center);
|
||||
Vector3 size = water.transform.TransformVector(water.Bounds.size);
|
||||
Handles.color = Color.yellow;
|
||||
Handles.DrawWireCube(center, size);
|
||||
}
|
||||
|
||||
private void DrawWaveMaskBounds()
|
||||
{
|
||||
if (Event.current == null)
|
||||
return;
|
||||
if (water.Profile == null)
|
||||
return;
|
||||
|
||||
Vector2 center = water.WaveMaskBounds.center;
|
||||
Vector3 worldCenter = new Vector3(center.x, water.transform.position.y, center.y);
|
||||
Vector2 size = water.WaveMaskBounds.size;
|
||||
Vector3 worldSize = new Vector3(size.x, 0.01f, size.y);
|
||||
Handles.color = Color.cyan;
|
||||
Handles.DrawWireCube(worldCenter, worldSize);
|
||||
}
|
||||
|
||||
public void DrawDebugGUI()
|
||||
{
|
||||
string label = "Debug";
|
||||
string id = "debug" + water.GetInstanceID().ToString();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
Camera[] cams = water.GetComponentsInChildren<Camera>();
|
||||
for (int i = 0; i < cams.Length; ++i)
|
||||
{
|
||||
if (!cams[i].name.StartsWith("~"))
|
||||
continue;
|
||||
if (cams[i].targetTexture == null)
|
||||
continue;
|
||||
EditorGUILayout.LabelField(cams[i].name);
|
||||
Rect r = GUILayoutUtility.GetAspectRect(1);
|
||||
EditorGUI.DrawPreviewTexture(r, cams[i].targetTexture);
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public override bool RequiresConstantRepaint()
|
||||
{
|
||||
return willDrawDebugGUI;
|
||||
}
|
||||
|
||||
private void OnRenderCamera(Camera cam)
|
||||
{
|
||||
bool isWaveSectionExpanded = PEditorCommon.IsFoldoutExpanded("water-profile-wave");
|
||||
if (isWaveSectionExpanded && water.UseWaveMask)
|
||||
{
|
||||
if (waveMaskVisMode != PWaveMaskVisualizationMode.None)
|
||||
{
|
||||
Vector2 center = water.WaveMaskBounds.center;
|
||||
Vector3 worldCenter = new Vector3(center.x, water.transform.position.y, center.y);
|
||||
Vector2 size = water.WaveMaskBounds.size;
|
||||
Vector3 worldSize = new Vector3(size.x, size.y, 1);
|
||||
|
||||
MaskVisualizerMaterial.SetTexture("_MainTex", water.WaveMask);
|
||||
MaskVisualizerMaterial.DisableKeyword("FLOW");
|
||||
MaskVisualizerMaterial.DisableKeyword("CREST");
|
||||
MaskVisualizerMaterial.DisableKeyword("HEIGHT");
|
||||
//if (waveMaskVisMode == PWaveMaskVisualizationMode.Flow)
|
||||
//{
|
||||
// MaskVisualizerMaterial.EnableKeyword("FLOW");
|
||||
//}
|
||||
//else
|
||||
if (waveMaskVisMode == PWaveMaskVisualizationMode.Crest)
|
||||
{
|
||||
MaskVisualizerMaterial.EnableKeyword("CREST");
|
||||
}
|
||||
else if (waveMaskVisMode == PWaveMaskVisualizationMode.Height)
|
||||
{
|
||||
MaskVisualizerMaterial.EnableKeyword("HEIGHT");
|
||||
}
|
||||
|
||||
Graphics.DrawMesh(
|
||||
QuadMesh,
|
||||
Matrix4x4.TRS(worldCenter, Quaternion.Euler(90, 0, 0), worldSize),
|
||||
MaskVisualizerMaterial,
|
||||
0,
|
||||
cam,
|
||||
0,
|
||||
null,
|
||||
ShadowCastingMode.Off,
|
||||
false,
|
||||
null,
|
||||
LightProbeUsage.Off,
|
||||
null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRenderCameraSRP(ScriptableRenderContext context, Camera cam)
|
||||
{
|
||||
OnRenderCamera(cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 91dc0346f67e24246a4b9ca11000c0d0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon
|
||||
{
|
||||
[CustomEditor(typeof(PWaterProfile))]
|
||||
public class PWaterProfileInspector : Editor
|
||||
{
|
||||
private PWaterProfile instance;
|
||||
private void OnEnable()
|
||||
{
|
||||
instance = target as PWaterProfile;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Select the associated water in the scene to edit this profile.", PEditorCommon.WordWrapItalicLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 09bf2b12f5c4f3047a75dc3c14800f5c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8766a47346cf5384e831a2fa74e14e1a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,170 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Rendering;
|
||||
#if UNITY_POST_PROCESSING_STACK_V2
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
#endif
|
||||
#if POSEIDON_URP
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using Pinwheel.Poseidon.FX.Universal;
|
||||
#endif
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pinwheel.Poseidon.FX
|
||||
{
|
||||
[CustomEditor(typeof(PWaterFX))]
|
||||
public class PWaterFXInspector : Editor
|
||||
{
|
||||
private PWaterFX instance;
|
||||
private void OnEnable()
|
||||
{
|
||||
instance = target as PWaterFX;
|
||||
SceneView.duringSceneGui += DuringSceneGUI;
|
||||
|
||||
if (instance.Profile != null)
|
||||
{
|
||||
instance.UpdatePostProcessOrVolumeProfile();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
SceneView.duringSceneGui -= DuringSceneGUI;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
bool willDrawGUI = false;
|
||||
string msg = null;
|
||||
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Builtin)
|
||||
{
|
||||
#if UNITY_POST_PROCESSING_STACK_V2
|
||||
willDrawGUI = true;
|
||||
#else
|
||||
msg = "Please install Post Processing Stack V2 to setup water effect";
|
||||
#endif
|
||||
}
|
||||
else if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
|
||||
{
|
||||
#if POSEIDON_URP
|
||||
willDrawGUI = true;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
willDrawGUI = false;
|
||||
msg = "Water effect doesn't support custom render pipeline.";
|
||||
}
|
||||
|
||||
if (!willDrawGUI)
|
||||
{
|
||||
EditorGUILayout.LabelField(msg, PEditorCommon.WordWrapItalicLabel);
|
||||
return;
|
||||
}
|
||||
|
||||
#if POSEIDON_URP
|
||||
if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal)
|
||||
{
|
||||
if (!CheckRendererFeatureConfig())
|
||||
{
|
||||
EditorGUILayout.LabelField("Please add a Water Effect Renderer Feature to the current URP Asset to setup water effect.", PEditorCommon.WordWrapItalicLabel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
instance.Water = EditorGUILayout.ObjectField("Water", instance.Water, typeof(PWater), true) as PWater;
|
||||
instance.Profile = PEditorCommon.ScriptableObjectField<PWaterFXProfile>("Profile", instance.Profile);
|
||||
|
||||
if (instance.Water == null || instance.Profile == null)
|
||||
return;
|
||||
DrawVolumesGUI();
|
||||
EditorGUI.BeginChangeCheck();
|
||||
PWaterFXProfileInspectorDrawer.Create(instance.Profile, instance.Water).DrawGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
instance.UpdatePostProcessOrVolumeProfile();
|
||||
}
|
||||
DrawEventsGUI();
|
||||
}
|
||||
|
||||
#if POSEIDON_URP
|
||||
private bool CheckRendererFeatureConfig()
|
||||
{
|
||||
UniversalRenderPipelineAsset uAsset = UniversalRenderPipeline.asset;
|
||||
ScriptableRenderer renderer = uAsset.scriptableRenderer;
|
||||
PropertyInfo rendererFeaturesProperty = renderer.GetType().GetProperty("rendererFeatures", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (rendererFeaturesProperty != null)
|
||||
{
|
||||
List<ScriptableRendererFeature> rendererFeatures = rendererFeaturesProperty.GetValue(renderer) as List<ScriptableRendererFeature>;
|
||||
if (rendererFeatures != null)
|
||||
{
|
||||
bool waterFxFeatureAdded = false;
|
||||
for (int i=0;i<rendererFeatures.Count;++i)
|
||||
{
|
||||
if (rendererFeatures[i] is PWaterEffectRendererFeature)
|
||||
{
|
||||
waterFxFeatureAdded = true;
|
||||
}
|
||||
}
|
||||
return waterFxFeatureAdded;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
private void DrawVolumesGUI()
|
||||
{
|
||||
string label = "Volumes";
|
||||
string id = "volumes" + instance.GetInstanceID();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
instance.VolumeExtent = PEditorCommon.InlineVector3Field("Extent", instance.VolumeExtent);
|
||||
instance.VolumeLayer = EditorGUILayout.LayerField("Layer", instance.VolumeLayer);
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawEventsGUI()
|
||||
{
|
||||
string label = "Events";
|
||||
string id = "events" + instance.GetInstanceID();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
SerializedObject so = new SerializedObject(instance);
|
||||
SerializedProperty sp0 = so.FindProperty("onEnterWater");
|
||||
if (sp0 != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(sp0);
|
||||
}
|
||||
|
||||
SerializedProperty sp1 = so.FindProperty("onExitWater");
|
||||
if (sp1 != null)
|
||||
{
|
||||
EditorGUILayout.PropertyField(sp1);
|
||||
}
|
||||
so.ApplyModifiedProperties();
|
||||
});
|
||||
}
|
||||
|
||||
private void DuringSceneGUI(SceneView sv)
|
||||
{
|
||||
if (instance.Water == null || instance.Profile == null)
|
||||
return;
|
||||
|
||||
Bounds waterBounds = instance.Water.Bounds;
|
||||
Vector3 size = waterBounds.size + instance.VolumeExtent;
|
||||
|
||||
Color color = Handles.yAxisColor;
|
||||
Matrix4x4 matrix = Matrix4x4.TRS(waterBounds.center + instance.transform.position, instance.transform.rotation, instance.transform.localScale);
|
||||
using (var scope = new Handles.DrawingScope(color, matrix))
|
||||
{
|
||||
Handles.DrawWireCube(Vector3.zero, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c3726835830f7544e8fb1a79548b2761
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon.FX
|
||||
{
|
||||
[CustomEditor(typeof(PWaterFXProfile))]
|
||||
public class PWaterFXProfileInspector : Editor
|
||||
{
|
||||
private PWaterFXProfile instance;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
instance = target as PWaterFXProfile;
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
PWaterFXProfileInspectorDrawer.Create(instance, null).DrawGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b29231a8f69bc3e46ba5e8c572478c00
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,114 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.Poseidon.FX
|
||||
{
|
||||
public class PWaterFXProfileInspectorDrawer
|
||||
{
|
||||
private PWaterFXProfile instance;
|
||||
private PWater water;
|
||||
|
||||
private PWaterFXProfileInspectorDrawer(PWaterFXProfile instance, PWater water)
|
||||
{
|
||||
this.instance = instance;
|
||||
this.water = water;
|
||||
}
|
||||
|
||||
public static PWaterFXProfileInspectorDrawer Create(PWaterFXProfile instance, PWater water)
|
||||
{
|
||||
return new PWaterFXProfileInspectorDrawer(instance, water);
|
||||
}
|
||||
|
||||
public void DrawGUI()
|
||||
{
|
||||
EditorGUI.BeginChangeCheck();
|
||||
DrawUnderwaterGUI();
|
||||
DrawWetLensGUI();
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
EditorUtility.SetDirty(instance);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawUnderwaterGUI()
|
||||
{
|
||||
string label = "Underwater";
|
||||
string id = "underwater" + instance.GetInstanceID();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
instance.EnableUnderwater = EditorGUILayout.Toggle("Enable", instance.EnableUnderwater);
|
||||
if (instance.EnableUnderwater)
|
||||
{
|
||||
PEditorCommon.SpacePixel(0);
|
||||
EditorGUILayout.LabelField("Water Body", PEditorCommon.BoldHeader);
|
||||
instance.UnderwaterMaxDepth = EditorGUILayout.FloatField("Max Depth", instance.UnderwaterMaxDepth);
|
||||
instance.UnderwaterSurfaceColorBoost = EditorGUILayout.Slider("Surface Color Boost", instance.UnderwaterSurfaceColorBoost, 1f, 3f);
|
||||
|
||||
PEditorCommon.SpacePixel(0);
|
||||
EditorGUILayout.LabelField("Fog", PEditorCommon.BoldHeader);
|
||||
instance.UnderwaterShallowFogColor = EditorGUILayout.ColorField("Shallow Fog Color", instance.UnderwaterShallowFogColor);
|
||||
instance.UnderwaterDeepFogColor = EditorGUILayout.ColorField("Deep Fog Color", instance.UnderwaterDeepFogColor);
|
||||
instance.UnderwaterViewDistance = EditorGUILayout.FloatField("View Distance", instance.UnderwaterViewDistance);
|
||||
|
||||
PEditorCommon.SpacePixel(0);
|
||||
EditorGUILayout.LabelField("Caustic", PEditorCommon.BoldHeader);
|
||||
instance.UnderwaterEnableCaustic = EditorGUILayout.Toggle("Enable", instance.UnderwaterEnableCaustic);
|
||||
if (instance.UnderwaterEnableCaustic)
|
||||
{
|
||||
instance.UnderwaterCausticTexture = PEditorCommon.InlineTextureField("Texture", instance.UnderwaterCausticTexture, -1);
|
||||
instance.UnderwaterCausticSize = EditorGUILayout.FloatField("Size", instance.UnderwaterCausticSize);
|
||||
instance.UnderwaterCausticStrength = EditorGUILayout.Slider("Strength", instance.UnderwaterCausticStrength, 0f, 1f);
|
||||
}
|
||||
|
||||
PEditorCommon.SpacePixel(0);
|
||||
EditorGUILayout.LabelField("Distortion", PEditorCommon.BoldHeader);
|
||||
instance.UnderwaterEnableDistortion = EditorGUILayout.Toggle("Enable", instance.UnderwaterEnableDistortion);
|
||||
if (instance.UnderwaterEnableDistortion)
|
||||
{
|
||||
instance.UnderwaterDistortionTexture = PEditorCommon.InlineTextureField("Normal Map", instance.UnderwaterDistortionTexture, -1);
|
||||
instance.UnderwaterDistortionStrength = EditorGUILayout.FloatField("Strength", instance.UnderwaterDistortionStrength);
|
||||
instance.UnderwaterWaterFlowSpeed = EditorGUILayout.FloatField("Water Flow Speed", instance.UnderwaterWaterFlowSpeed);
|
||||
}
|
||||
PEditorCommon.Separator();
|
||||
}
|
||||
|
||||
if (water != null && instance.EnableUnderwater)
|
||||
{
|
||||
GUI.enabled = water.Profile != null;
|
||||
if (GUILayout.Button("Inherit Parameters"))
|
||||
{
|
||||
instance.UnderwaterMaxDepth = water.Profile.MaxDepth;
|
||||
instance.UnderwaterShallowFogColor = water.Profile.Color;
|
||||
instance.UnderwaterDeepFogColor = water.Profile.DepthColor;
|
||||
instance.UnderwaterEnableCaustic = water.Profile.EnableCaustic;
|
||||
instance.UnderwaterCausticTexture = water.Profile.CausticTexture;
|
||||
instance.UnderwaterCausticSize = water.Profile.CausticSize;
|
||||
instance.UnderwaterCausticStrength = water.Profile.CausticStrength;
|
||||
}
|
||||
GUI.enabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void DrawWetLensGUI()
|
||||
{
|
||||
string label = "Wet Lens";
|
||||
string id = "wet-lens" + instance.GetInstanceID();
|
||||
|
||||
PEditorCommon.Foldout(label, false, id, () =>
|
||||
{
|
||||
instance.EnableWetLens = EditorGUILayout.Toggle("Enable", instance.EnableWetLens);
|
||||
if (instance.EnableWetLens)
|
||||
{
|
||||
instance.WetLensNormalMap = PEditorCommon.InlineTextureField("Normal Map", instance.WetLensNormalMap, -1);
|
||||
instance.WetLensStrength = EditorGUILayout.Slider("Strength", instance.WetLensStrength, 0f, 1f);
|
||||
instance.WetLensDuration = EditorGUILayout.FloatField("Duration", instance.WetLensDuration);
|
||||
instance.WetLensFadeCurve = EditorGUILayout.CurveField("Fade", instance.WetLensFadeCurve, Color.red, new Rect(0, 0, 1, 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b391a0bf945395e44b4087de4fc66d76
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 639294d91651d874b9acb629cdc24635
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,31 @@
|
||||
#if UNITY_EDITOR && GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Poseidon.GriffinExtension
|
||||
{
|
||||
public static class PGriffinExtensionCommon
|
||||
{
|
||||
public static PWater FindTargetWaterObject()
|
||||
{
|
||||
PWater[] waters = Object.FindObjectsOfType<PWater>();
|
||||
for (int i=0;i<waters.Length;++i)
|
||||
{
|
||||
if (waters[i].gameObject.name.StartsWith("~"))
|
||||
{
|
||||
return waters[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PWater CreateTargetWaterObject()
|
||||
{
|
||||
PWater water = PEditorMenus.CreateCalmWaterHQObject(null);
|
||||
water.name = "~PoseidonWater";
|
||||
return water;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 443e1772d9e010648b32ed90a069b35e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,117 @@
|
||||
#if UNITY_EDITOR && GRIFFIN
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.Poseidon.GriffinExtension
|
||||
{
|
||||
//[CreateAssetMenu(menuName = "Poseidon/Water Quick Setup Config")]
|
||||
public class PWaterQuickSetupConfig : ScriptableObject
|
||||
{
|
||||
private static PWaterQuickSetupConfig instance;
|
||||
public static PWaterQuickSetupConfig Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = Resources.Load<PWaterQuickSetupConfig>("WaterQuickSetupConfig");
|
||||
if (instance == null)
|
||||
{
|
||||
instance = ScriptableObject.CreateInstance<PWaterQuickSetupConfig>();
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float waterLevel;
|
||||
public float WaterLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
return waterLevel;
|
||||
}
|
||||
set
|
||||
{
|
||||
waterLevel = value;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private int meshResolution;
|
||||
public int MeshResolution
|
||||
{
|
||||
get
|
||||
{
|
||||
return meshResolution;
|
||||
}
|
||||
set
|
||||
{
|
||||
meshResolution = Mathf.Clamp(value, 2, 100);
|
||||
if (meshResolution % 2 == 1)
|
||||
{
|
||||
meshResolution -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float meshNoise;
|
||||
public float MeshNoise
|
||||
{
|
||||
get
|
||||
{
|
||||
return meshNoise;
|
||||
}
|
||||
set
|
||||
{
|
||||
meshNoise = Mathf.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float approximateSizeX;
|
||||
public float ApproximateSizeX
|
||||
{
|
||||
get
|
||||
{
|
||||
return approximateSizeX;
|
||||
}
|
||||
set
|
||||
{
|
||||
approximateSizeX = Mathf.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private float approximateSizeZ;
|
||||
public float ApproximateSizeZ
|
||||
{
|
||||
get
|
||||
{
|
||||
return approximateSizeZ;
|
||||
}
|
||||
set
|
||||
{
|
||||
approximateSizeZ = Mathf.Max(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
private Vector2 tileSize;
|
||||
public Vector2 TileSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return tileSize;
|
||||
}
|
||||
set
|
||||
{
|
||||
tileSize = new Vector2(Mathf.Max(1, value.x), Mathf.Max(1, value.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d7f31d2ebf097e84998b1e56436b331a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,255 @@
|
||||
#if GRIFFIN && UNITY_EDITOR && POSEIDON
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using Pinwheel.Poseidon;
|
||||
using Pinwheel.Griffin;
|
||||
|
||||
namespace Pinwheel.Poseidon.GriffinExtension
|
||||
{
|
||||
public static class PWaterQuickSetupGriffinExtension
|
||||
{
|
||||
private const string GX_POSEIDON_WATER_QUICK_SETUP = "http://bit.ly/2qb2gLO";
|
||||
|
||||
public static string GetExtensionName()
|
||||
{
|
||||
return "Poseidon - Water Quick Setup";
|
||||
}
|
||||
|
||||
public static string GetPublisherName()
|
||||
{
|
||||
return "Pinwheel Studio";
|
||||
}
|
||||
|
||||
public static string GetDescription()
|
||||
{
|
||||
return
|
||||
"Quickly add low poly water which fit into your scene mood.";
|
||||
}
|
||||
|
||||
public static string GetVersion()
|
||||
{
|
||||
return "v1.0.0";
|
||||
}
|
||||
|
||||
public static void OpenSupportLink()
|
||||
{
|
||||
PEditorCommon.OpenEmailEditor(
|
||||
"customer@pinwheel.studio",
|
||||
"Griffin Extension - Poseidon",
|
||||
"YOUR_MESSAGE_HERE");
|
||||
}
|
||||
|
||||
public static void OnGUI()
|
||||
{
|
||||
PWater water = PGriffinExtensionCommon.FindTargetWaterObject();
|
||||
if (water == null)
|
||||
{
|
||||
DrawCreateWaterGUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawWaterConfigGUI(water);
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawCreateWaterGUI()
|
||||
{
|
||||
if (GUILayout.Button("Add Low Poly Water"))
|
||||
{
|
||||
GAnalytics.Record(GX_POSEIDON_WATER_QUICK_SETUP);
|
||||
InitDefaultConfigs();
|
||||
AddWater();
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitDefaultConfigs()
|
||||
{
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
config.WaterLevel = 1;
|
||||
config.MeshResolution = 100;
|
||||
config.MeshNoise = 0;
|
||||
|
||||
Bounds levelBounds = GCommon.GetLevelBounds();
|
||||
config.ApproximateSizeX = levelBounds.size.x;
|
||||
config.ApproximateSizeZ = levelBounds.size.z;
|
||||
config.TileSize = Vector2.one * 100;
|
||||
}
|
||||
|
||||
private static void AddWater()
|
||||
{
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
PWater water = PGriffinExtensionCommon.CreateTargetWaterObject();
|
||||
water.TileSize = config.TileSize;
|
||||
water.MeshResolution = config.MeshResolution;
|
||||
water.MeshNoise = config.MeshNoise;
|
||||
water.GeneratePlaneMesh();
|
||||
|
||||
CenterToLevel(water);
|
||||
MatchWaterLevel(water);
|
||||
MatchWaterSize(water);
|
||||
|
||||
Selection.activeGameObject = water.gameObject;
|
||||
}
|
||||
|
||||
private static void CenterToLevel(PWater water)
|
||||
{
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
Bounds levelBounds = GCommon.GetLevelBounds();
|
||||
water.transform.position = new Vector3(levelBounds.center.x, config.WaterLevel, levelBounds.center.z);
|
||||
}
|
||||
|
||||
private static void MatchWaterLevel(PWater water)
|
||||
{
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
water.transform.position = new Vector3(water.transform.position.x, config.WaterLevel, water.transform.position.z);
|
||||
}
|
||||
|
||||
private static void MatchWaterSize(PWater water)
|
||||
{
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
water.TileSize = config.TileSize;
|
||||
int radiusX = 1 + Mathf.FloorToInt(config.ApproximateSizeX * 0.5f / water.TileSize.x);
|
||||
int radiusZ = 1 + Mathf.FloorToInt(config.ApproximateSizeZ * 0.5f / water.TileSize.y);
|
||||
|
||||
water.TileIndices.Clear();
|
||||
for (int x = -radiusX; x < radiusX; ++x)
|
||||
{
|
||||
for (int z = -radiusZ; z < radiusZ; ++z)
|
||||
{
|
||||
water.TileIndices.AddIfNotContains(new PIndex2D(x, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void DrawWaterConfigGUI(PWater water)
|
||||
{
|
||||
DrawTemplateSelectionGUI(water);
|
||||
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
bool changed = false;
|
||||
bool meshChanged = false;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
config.WaterLevel = EditorGUILayout.FloatField("Water Level", config.WaterLevel);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
config.MeshResolution = EditorGUILayout.DelayedIntField("Resolution", config.MeshResolution);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
meshChanged = true;
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
config.MeshNoise = EditorGUILayout.FloatField("Noise", config.MeshNoise);
|
||||
config.ApproximateSizeX = EditorGUILayout.FloatField("Approx. Size X", config.ApproximateSizeX);
|
||||
config.ApproximateSizeZ = EditorGUILayout.FloatField("Approx. Size Z", config.ApproximateSizeZ);
|
||||
config.TileSize = PEditorCommon.InlineVector2Field("Tile Size", config.TileSize);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (meshChanged)
|
||||
{
|
||||
water.GeneratePlaneMesh();
|
||||
}
|
||||
|
||||
if (changed || meshChanged)
|
||||
{
|
||||
water.MeshNoise = config.MeshNoise;
|
||||
water.TileSize = config.TileSize;
|
||||
water.UpdateMaterial();
|
||||
MatchWaterLevel(water);
|
||||
MatchWaterSize(water);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(config);
|
||||
|
||||
GEditorCommon.Separator();
|
||||
if (GUILayout.Button("Center To Level Bounds"))
|
||||
{
|
||||
CenterToLevel(water);
|
||||
}
|
||||
if (GUILayout.Button("Fill Level Bounds"))
|
||||
{
|
||||
Bounds levelBounds = GCommon.GetLevelBounds();
|
||||
config.ApproximateSizeX = levelBounds.size.x;
|
||||
config.ApproximateSizeZ = levelBounds.size.z;
|
||||
CenterToLevel(water);
|
||||
MatchWaterSize(water);
|
||||
}
|
||||
if (GUILayout.Button("Done"))
|
||||
{
|
||||
Done(water);
|
||||
}
|
||||
}
|
||||
|
||||
private const string WATER_TEMPLATE_RESOURCES_PATH = "WaterTemplates";
|
||||
private static Rect templatePopupRect;
|
||||
private static void DrawTemplateSelectionGUI(PWater water)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.PrefixLabel("Template");
|
||||
Rect r = EditorGUILayout.GetControlRect();
|
||||
if (Event.current.type == EventType.Repaint)
|
||||
{
|
||||
templatePopupRect = r;
|
||||
}
|
||||
|
||||
if (GUI.Button(r, "Select", EditorStyles.popup))
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
PWaterProfile[] templates = Resources.LoadAll<PWaterProfile>(WATER_TEMPLATE_RESOURCES_PATH);
|
||||
if (templates.Length == 0)
|
||||
{
|
||||
menu.AddDisabledItem(new GUIContent("No Template found!"));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < templates.Length; ++i)
|
||||
{
|
||||
int index = i;
|
||||
string label = templates[i].name.Replace("_", "/");
|
||||
menu.AddItem(
|
||||
new GUIContent(label),
|
||||
false,
|
||||
() =>
|
||||
{
|
||||
ApplyTemplate(water, templates[index]);
|
||||
});
|
||||
}
|
||||
}
|
||||
menu.DropDown(templatePopupRect);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private static void ApplyTemplate(PWater water, PWaterProfile template)
|
||||
{
|
||||
water.Profile.CopyFrom(template);
|
||||
|
||||
PWaterQuickSetupConfig config = PWaterQuickSetupConfig.Instance;
|
||||
water.MeshResolution = config.MeshResolution;
|
||||
water.MeshNoise = config.MeshNoise;
|
||||
water.GeneratePlaneMesh();
|
||||
water.UpdateMaterial();
|
||||
water.TileSize = config.TileSize;
|
||||
MatchWaterLevel(water);
|
||||
MatchWaterSize(water);
|
||||
}
|
||||
|
||||
private static void Done(PWater water)
|
||||
{
|
||||
water.name = water.name.Replace("~", "");
|
||||
Selection.activeGameObject = water.gameObject;
|
||||
EditorGUIUtility.PingObject(water.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 855f18207cd40714aa5eb5abd870c2a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user