升级水插件

This commit is contained in:
2026-01-08 22:30:55 +08:00
parent febff82d24
commit ca68084264
415 changed files with 18138 additions and 7134 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2a5b1db7ccbfeda46871d9c365e6a914
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// Define empty namespaces for when assemblies are not present.
namespace WaveHarmonic.Crest.ShallowWater { }

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a1364267b3de043daae23dda97c99063
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,259 @@
// Crest Water System
// Copyright © 2024 Wave Harmonic. All rights reserved.
// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE)
using Gaia;
using UnityEditor;
using UnityEngine;
using WaveHarmonic.Crest.ShallowWater;
namespace WaveHarmonic.Crest
{
sealed class GRC_Crest : GaiaRuntimeComponent
{
[SerializeField]
bool _Wind = true;
[SerializeField]
bool _Swell = true;
[SerializeField]
bool _ShallowWater = true;
GUIContent _HelpLink;
GUIContent _PanelLabel;
/// <inheritdoc/>
public override GUIContent PanelLabel
{
get
{
if (_PanelLabel == null || _PanelLabel.text == "")
{
_PanelLabel = new GUIContent("Crest Water", "Adds Crest Water to your scene.");
}
return _PanelLabel;
}
}
/// <inheritdoc/>
public override void Initialize()
{
// Order components appear in the UI. Try to keep in alphabetical order.
m_orderNumber = 210;
if (_HelpLink == null || _HelpLink.text == "")
{
_HelpLink = new GUIContent("Crest Online documentation", "Opens the documentation for the Crest Water System in your browser.");
}
}
/// <inheritdoc/>
public override void DrawUI()
{
// Displays "?" help button.
DisplayHelp
(
"This module adds the Crest Water System to your scene. Please visit the link to learn more:",
_HelpLink,
"https://docs.crest.waveharmonic.com/About/Introduction.html"
);
EditorGUI.BeginChangeCheck();
{
_Swell = EditorGUILayout.Toggle("Swell Waves", _Swell);
DisplayHelp("Whether to add swell waves to the scene. Swell waves will come from conditions far away from the scene. Modify the component after creation to customize.");
_Wind = EditorGUILayout.Toggle("Wind Waves", _Wind);
DisplayHelp("Whether to add wind waves to the scene. These waves are based on local wind conditions. Requires Gaia's Wind Zone (note that the defaul wind value will produce no waves). Modify the component after creation to customize.");
#if d_WaveHarmonic_Crest_ShallowWater
_ShallowWater = EditorGUILayout.Toggle("Shoreline Simulation", _ShallowWater);
DisplayHelp("Whether to add a shoreline shallow water simulation to the scene. Modify the component after creation to customize.");
#endif
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
if (GUILayout.Button("Remove")) RemoveFromScene();
GUILayout.Space(15);
if (GUILayout.Button("Apply")) AddToScene();
GUILayout.EndHorizontal();
}
if (EditorGUI.EndChangeCheck())
{
EditorUtility.SetDirty(this);
}
}
/// Called when either "Apply" or "Create Runtime" is pressed.
/// <inheritdoc/>
public override void AddToScene()
{
// Re-initialize to keep user's changes.
var water = FindFirstObjectByType<WaterRenderer>(FindObjectsInactive.Include);
if (water == null)
{
water = new GameObject("Water").AddComponent<WaterRenderer>();
}
// Sea level is height above terrain bottom.
var seaLevel = GaiaAPI.GetSeaLevel();
water.transform.position = new Vector3(0f, seaLevel, 0f);
var managed = water.transform.Find("Managed");
if (managed == null)
{
managed = new GameObject("Managed").transform;
}
managed.SetParent(water.transform, worldPositionStays: false);
// Wind
if (_Wind)
{
var wind = FindFirstObjectByType<WindManager>();
if (wind != null)
{
water.WindZone = wind.GetComponent<WindZone>();
}
}
// Depth
water.DepthLod.IncludeTerrainHeight = false;
foreach (var terrain in FindObjectsByType<Terrain>(FindObjectsInactive.Include, FindObjectsSortMode.None))
{
var dp = terrain.GetComponentInChildren<DepthProbe>(includeInactive: true);
if (dp == null)
{
dp = new GameObject("WaterDepthProbe").AddComponent<DepthProbe>();
}
dp.gameObject.layer = water.Surface.Layer;
dp.transform.SetParent(terrain.transform, worldPositionStays: false);
dp.transform.localPosition = terrain.terrainData.size * 0.5f;
var position = dp.transform.position;
position.y = seaLevel;
dp.transform.position = position;
dp.transform.localScale = new(terrain.terrainData.size.x, 1f, terrain.terrainData.size.z);
dp.Layers = 1 << terrain.gameObject.layer;
// 1m below terrain bottom to 1m above maximum terrain height.
dp.CaptureRange = new(-seaLevel + -1f, terrain.terrainData.size.y - seaLevel + 1);
dp.Resolution = terrain.terrainData.heightmapResolution - 1;
dp.Populate();
}
// Wind Waves
if (_Wind && water.WindZone != null)
{
GetOrAddComponentToScene<ShapeFFT>(managed, "WaterWindWaves", out _);
}
else
{
RemoveComponentFromScene<ShapeFFT>(managed);
}
// Swell Waves
if (_Swell)
{
GetOrAddComponentToScene<ShapeGerstner>(managed, "WaterSwellWaves", out var waves);
waves.OverrideGlobalWindDirection = true;
waves.OverrideGlobalWindSpeed = true;
waves.ReverseWaveWeight = 0;
waves.Swell = true;
if (!waves.TryGetComponent<ShapeFFT>(out var fft))
{
fft = waves.gameObject.AddComponent<ShapeFFT>();
fft.Spectrum = AssetDatabase.LoadAssetAtPath<WaveSpectrum>("Packages/com.waveharmonic.crest/Runtime/Data/WaveSpectra/WavesSwell.asset");
}
fft.OverrideGlobalWindDirection = true;
fft.OverrideGlobalWindSpeed = true;
fft.OverrideGlobalWindTurbulence = true;
fft.WindAlignment = 0.5f;
}
else
{
RemoveComponentFromScene<ShapeGerstner>(managed);
}
#if d_WaveHarmonic_Crest_ShallowWater
if (_ShallowWater)
{
water.FlowLod.Enabled = true;
if (GetOrAddComponentToScene<ShallowWaterSimulation>(managed, "ShorelineSimulation", out var sws))
{
water.Surface.Material = AssetDatabase.LoadAssetAtPath<Material>("Packages/com.waveharmonic.crest/Runtime/Materials/Water (Flow).mat");
sws.Width = 256;
}
if (!sws.TryGetComponent<DepthProbe>(out var dp))
{
dp = sws.gameObject.AddComponent<DepthProbe>();
}
dp.GenerateSignedDistanceField = false;
sws.Preset = ShallowWaterSimulationPreset.Shoreline;
sws.Placement = Placement.Viewpoint;
sws.DynamicSeabed = true;
}
else
{
RemoveComponentFromScene<ShallowWaterSimulation>(managed);
}
#endif
}
bool GetOrAddComponentToScene<T>(Transform managed, string name, out T component) where T : MonoBehaviour
{
component = managed.GetComponentInChildren<T>();
var create = component == null;
if (create)
{
component = new GameObject(name).AddComponent<T>();
component.transform.SetParent(managed.transform, worldPositionStays: false);
}
return create;
}
void RemoveComponentFromScene<T>(Transform managed) where T : MonoBehaviour
{
var component = managed.GetComponentInChildren<T>();
if (component != null)
{
DestroyImmediate(component.gameObject);
}
}
/// Called when "Remove" is pressed.
/// <inheritdoc/>
public override void RemoveFromScene()
{
var water = FindFirstObjectByType<WaterRenderer>(FindObjectsInactive.Include);
if (water != null) DestroyImmediate(water.gameObject);
foreach (var terrain in FindObjectsByType<Terrain>(FindObjectsInactive.Include, FindObjectsSortMode.None))
{
var depthCache = terrain.GetComponentInChildren<DepthProbe>(includeInactive: true);
if (depthCache != null) DestroyImmediate(depthCache.gameObject);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7f9d5fab14f7242db80be581a62d53c9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,32 @@
{
"name": "WaveHarmonic.Crest.Integration.Gaia",
"rootNamespace": "",
"references": [
"GUID:532136e3ad79fba44b9e7d74f4e53abe",
"GUID:cc49c744ac0d6fa459f6fb20f0066991",
"GUID:7c347618730f5467f86a58f333ce21df",
"GUID:98db37baed0fc4b73a47a9d66f791aae",
"GUID:056ff2a5b2f124d468c6655552acdca5",
"GUID:d365b04c036e04304a59ef9aa90b3924"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [
"UNITY_2022_3_OR_NEWER",
"GAIA_2023"
],
"versionDefines": [
{
"name": "com.waveharmonic.crest.shallow-water",
"expression": "",
"define": "d_WaveHarmonic_Crest_ShallowWater"
}
],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1c4070cb1d689471b80e17ee7aa518e6
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: