add some extra assets FX and SFX

This commit is contained in:
Robii Aragon
2026-03-29 23:03:14 -07:00
parent 6ef3eb1535
commit 24dc66a81e
10142 changed files with 2535978 additions and 36608 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 89b3d095043131f4c9793444b6d3e83e
folderAsset: yes
timeCreated: 1673260982
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5832314657fda4c4abe73d1069b14b16
folderAsset: yes
timeCreated: 1673260982
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
namespace NaughtyWaterBuoyancy
{
public class MinHeap<T>
{
private const int INITIAL_CAPACITY = 4;
private T[] arr;
private int lastItemIndex;
private IComparer<T> comparer;
public MinHeap()
: this(INITIAL_CAPACITY, Comparer<T>.Default)
{
}
public MinHeap(int capacity)
: this(capacity, Comparer<T>.Default)
{
}
public MinHeap(IComparer<T> comparer)
: this(INITIAL_CAPACITY, comparer)
{
}
public MinHeap(int capacity, IComparer<T> comparer)
{
this.arr = new T[capacity];
this.lastItemIndex = -1;
this.comparer = comparer;
}
public int Count
{
get
{
return this.lastItemIndex + 1;
}
}
public void Add(T item)
{
if (this.lastItemIndex == this.arr.Length - 1)
{
this.Resize();
}
this.lastItemIndex++;
this.arr[this.lastItemIndex] = item;
this.MinHeapifyUp(this.lastItemIndex);
}
public T Remove()
{
if (this.lastItemIndex == -1)
{
throw new InvalidOperationException("The heap is empty");
}
T removedItem = this.arr[0];
this.arr[0] = this.arr[this.lastItemIndex];
this.lastItemIndex--;
this.MinHeapifyDown(0);
return removedItem;
}
public T Peek()
{
if (this.lastItemIndex == -1)
{
throw new InvalidOperationException("The heap is empty");
}
return this.arr[0];
}
public void Clear()
{
this.lastItemIndex = -1;
this.arr = new T[INITIAL_CAPACITY];
}
private void MinHeapifyUp(int index)
{
if (index == 0)
{
return;
}
int childIndex = index;
int parentIndex = (index - 1) / 2;
if (this.comparer.Compare(this.arr[childIndex], this.arr[parentIndex]) < 0)
{
// swap the parent and the child
T temp = this.arr[childIndex];
this.arr[childIndex] = this.arr[parentIndex];
this.arr[parentIndex] = temp;
this.MinHeapifyUp(parentIndex);
}
}
private void MinHeapifyDown(int index)
{
int leftChildIndex = index * 2 + 1;
int rightChildIndex = index * 2 + 2;
int smallestItemIndex = index; // The index of the parent
if (leftChildIndex <= this.lastItemIndex &&
this.comparer.Compare(this.arr[leftChildIndex], this.arr[smallestItemIndex]) < 0)
{
smallestItemIndex = leftChildIndex;
}
if (rightChildIndex <= this.lastItemIndex &&
this.comparer.Compare(this.arr[rightChildIndex], this.arr[smallestItemIndex]) < 0)
{
smallestItemIndex = rightChildIndex;
}
if (smallestItemIndex != index)
{
// swap the parent with the smallest of the child items
T temp = this.arr[index];
this.arr[index] = this.arr[smallestItemIndex];
this.arr[smallestItemIndex] = temp;
this.MinHeapifyDown(smallestItemIndex);
}
}
private void Resize()
{
T[] newArr = new T[this.arr.Length * 2];
for (int i = 0; i < this.arr.Length; i++)
{
newArr[i] = this.arr[i];
}
this.arr = newArr;
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: fa59aefaf83f1464194ca05a3d77864f
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/Collections/MinHeap.cs
uploadId: 889948

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 9e6de35f7fd668f43b04f03ab20f61dd
folderAsset: yes
timeCreated: 1673260982
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
public static class ColliderUtils
{
public static bool IsPointInsideCollider (Vector3 point, Collider collider, ref Bounds colliderBounds)
{
float rayLength = colliderBounds.size.magnitude;
Ray ray = new Ray (point, collider.transform.position - point);
RaycastHit hit;
if (Physics.Raycast (ray, out hit, rayLength)) {
if (hit.collider == collider) {
return false;
}
}
return true;
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 302632b1eae360945b1072306f2e94de
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/Utils/ColliderUtils.cs
uploadId: 889948

View File

@@ -0,0 +1,31 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
public static class DebugUtils
{
public static void DrawPoint (Vector3 point)
{
DrawPoint (point, Color.white);
}
public static void DrawPoint (Vector3 point, Color color)
{
Debug.DrawLine (point - 0.1f * Vector3.right, point + 0.1f * Vector3.right, color);
Debug.DrawLine (point - 0.1f * Vector3.up, point + 0.1f * Vector3.up, color);
Debug.DrawLine (point - 0.1f * Vector3.forward, point + 0.1f * Vector3.forward, color);
}
public static void DrawPoint (float x, float y, float z)
{
DrawPoint (new Vector3 (x, y, z));
}
public static void DrawPoint (float x, float y, float z, Color color)
{
DrawPoint (new Vector3 (x, y, z), color);
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 9f7c7819a3e3e914baf0ad2b942bd8f6
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/Utils/DebugUtils.cs
uploadId: 889948

View File

@@ -0,0 +1,132 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
public static class MathfUtils
{
public static float GetAverageValue (params float[] values)
{
float sum = 0;
for (int i = 0; i < values.Length; i++) {
sum += values [i];
}
return sum / values.Length;
}
public static Vector3 GetAveratePoint (params Vector3[] points)
{
Vector3 sum = Vector3.zero;
for (int i = 0; i < points.Length; i++) {
sum += points [i];
}
return sum / points.Length;
}
public static bool IsPointInsideTriangle (Vector3 point, Vector3 tp1, Vector3 tp2, Vector3 tp3)
{
float trueArea = CalculateArea_Triangle (tp1, tp2, tp3);
float checkArea =
CalculateArea_Triangle (point, tp1, tp2) +
CalculateArea_Triangle (point, tp2, tp3) +
CalculateArea_Triangle (point, tp3, tp1);
return Mathf.Abs (trueArea - checkArea) < 0.01f;
}
public static bool IsPointInsideTriangle (Vector3 point, Vector3 tp1, Vector3 tp2, Vector3 tp3, bool ignoreX, bool ignoreY, bool ignoreZ)
{
if (ignoreX) {
point.x = 0f;
tp1.x = 0f;
tp2.x = 0f;
tp3.x = 0f;
}
if (ignoreY) {
point.y = 0f;
tp1.y = 0f;
tp2.y = 0f;
tp3.y = 0f;
}
if (ignoreZ) {
point.z = 0f;
tp1.z = 0f;
tp2.z = 0f;
tp3.z = 0f;
}
return IsPointInsideTriangle (point, tp1, tp2, tp3);
}
public static bool IsPointInsideTriangle (Vector3 point, Vector3[] triangle)
{
return IsPointInsideTriangle (point, triangle [0], triangle [1], triangle [2]);
}
public static bool IsPointInsideTriangle (Vector3 point, Vector3[] triangle, bool ignoreX, bool ignoreY, bool ignoreZ)
{
return IsPointInsideTriangle (point, triangle [0], triangle [1], triangle [2], ignoreX, ignoreY, ignoreZ);
}
public static float CalculateArea_Triangle (Vector3 p1, Vector3 p2, Vector3 p3)
{
float a = (p1 - p2).magnitude;
float b = (p1 - p3).magnitude;
float c = (p2 - p3).magnitude;
float p = (a + b + c) / 2f; // The half perimeter
return Mathf.Sqrt (p * (p - a) * (p - b) * (p - c));
}
public static float CalculateArea_Triangle (Vector3[] triangle)
{
return CalculateArea_Triangle (triangle [0], triangle [1], triangle [2]);
}
public static float CalculateVolume_Mesh (Mesh mesh, Transform trans)
{
float volume = 0f;
Vector3[] vertices = mesh.vertices;
int[] triangles = mesh.triangles;
for (int i = 0; i < mesh.triangles.Length; i += 3) {
Vector3 p1 = vertices [triangles [i + 0]];
Vector3 p2 = vertices [triangles [i + 1]];
Vector3 p3 = vertices [triangles [i + 2]];
volume += CalculateVolume_Tetrahedron (p1, p2, p3, Vector3.zero);
}
return Mathf.Abs (volume) * trans.localScale.x * trans.localScale.y * trans.localScale.z;
}
public static float CalculateVolume_Tetrahedron (Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4)
{
Vector3 a = p1 - p2;
Vector3 b = p1 - p3;
Vector3 c = p1 - p4;
return (Vector3.Dot (a, Vector3.Cross (b, c))) / 6f;
////float v321 = p3.x * p2.y * p1.z;
////float v231 = p2.x * p3.y * p1.z;
////float v312 = p3.x * p1.y * p2.z;
////float v132 = p1.x * p3.y * p2.z;
////float v213 = p2.x * p1.y * p3.z;
////float v123 = p1.x * p2.y * p3.z;
////return (1f / 6f) * (-v321 + v231 + v312 - v132 - v213 + v123);
}
public static float CalculateVolume_Tetrahedron (Vector3[] tetrahedron)
{
return CalculateVolume_Tetrahedron (tetrahedron [0], tetrahedron [1], tetrahedron [2], tetrahedron [3]);
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 55521a36976c5c7479786d131c761081
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/Utils/MathfUtils.cs
uploadId: 889948

View File

@@ -0,0 +1,12 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
public static class StringUtils
{
public static string Vector3ToString (Vector3 vector)
{
return string.Format ("({0:f3}, {1:f3}, {2:f3})", vector.x, vector.y, vector.z);
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: a8e4503a9bca163499143e39a58d67a4
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/Utils/StringUtils.cs
uploadId: 889948

View File

@@ -0,0 +1,547 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
[ExecuteInEditMode] // Make water live-update even when not in play mode
public class WaterFX : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool updateFXOnEditorEnabled;
public bool updateFXInGameEnabled;
public enum WaterMode
{
Simple = 0,
Reflective = 1,
Refractive = 2,
};
[SerializeField]
private WaterMode waterMode = WaterMode.Refractive;
[SerializeField]
private bool disablePixelLights = true;
[SerializeField]
private int textureSize = 256;
[SerializeField]
private float clipPlaneOffset = 0.07f;
[SerializeField]
private LayerMask reflectLayers = -1;
[SerializeField]
private LayerMask refractLayers = -1;
private Dictionary<Camera, Camera> m_ReflectionCameras = new Dictionary<Camera, Camera> ();
// Camera -> Camera table
private Dictionary<Camera, Camera> m_RefractionCameras = new Dictionary<Camera, Camera> ();
// Camera -> Camera table
private RenderTexture m_ReflectionTexture;
private RenderTexture m_RefractionTexture;
private WaterMode m_HardwareWaterSupport = WaterMode.Refractive;
private int m_OldReflectionTextureSize;
private int m_OldRefractionTextureSize;
private static bool s_InsideWater;
public string _ReflectionTexName = "_ReflectionTex";
int _ReflectionTexNameID = -1;
public string _RefractionTexName = "_RefractionTex";
int _RefractionTexNameID = -1;
public string WaveSpeedName = "WaveSpeed";
int WaveSpeedNameID = -1;
public string _WaveScaleName = "_WaveScale";
int _WaveScaleNameID = -1;
public string _WaveOffsetName = "_WaveOffset";
int _WaveOffsetNameID = -1;
public string _WaveScale4Name = "_WaveScale4";
int _WaveScale4NameID = -1;
Renderer mainRenderer;
// This is called when it's known that the object will be rendered by some
// camera. We render reflections / refractions and do other updates here.
// Because the script executes in edit mode, reflections for the scene view
// camera will just work!
public void OnWillRenderObject ()
{
if (!Application.isPlaying) {
if (!updateFXOnEditorEnabled) {
return;
}
} else {
if (!updateFXInGameEnabled) {
return;
}
}
if (!enabled) {
return;
}
if (mainRenderer == null) {
mainRenderer = GetComponent<Renderer> ();
}
if (mainRenderer == null || mainRenderer.sharedMaterial == null || !mainRenderer.enabled) {
return;
}
Camera cam = Camera.current;
if (cam == null) {
return;
}
// Safeguard from recursive water reflections.
if (s_InsideWater) {
return;
}
s_InsideWater = true;
// Actual water rendering mode depends on both the current setting AND
// the hardware support. There's no point in rendering refraction textures
// if they won't be visible in the end.
m_HardwareWaterSupport = FindHardwareWaterSupport ();
WaterMode mode = GetWaterMode ();
Camera reflectionCamera, refractionCamera;
CreateWaterObjects (cam, out reflectionCamera, out refractionCamera);
// find out the reflection plane: position and normal in world space
Vector3 pos = transform.position;
Vector3 normal = transform.up;
// Optionally disable pixel lights for reflection/refraction
int oldPixelLightCount = QualitySettings.pixelLightCount;
if (disablePixelLights) {
QualitySettings.pixelLightCount = 0;
}
UpdateCameraModes (cam, reflectionCamera);
UpdateCameraModes (cam, refractionCamera);
// Render reflection if needed
if (mode >= WaterMode.Reflective) {
// Reflect camera around reflection plane
float d = -Vector3.Dot (normal, pos) - clipPlaneOffset;
Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d);
Matrix4x4 reflection = Matrix4x4.zero;
CalculateReflectionMatrix (ref reflection, reflectionPlane);
Vector3 oldpos = cam.transform.position;
Vector3 newpos = reflection.MultiplyPoint (oldpos);
reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
// Setup oblique projection matrix so that near plane is our reflection
// plane. This way we clip everything below/above it for free.
Vector4 clipPlane = CameraSpacePlane (reflectionCamera, pos, normal, 1.0f);
reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix (clipPlane);
reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer
reflectionCamera.targetTexture = m_ReflectionTexture;
GL.invertCulling = true;
reflectionCamera.transform.position = newpos;
Vector3 euler = cam.transform.eulerAngles;
reflectionCamera.transform.eulerAngles = new Vector3 (-euler.x, euler.y, euler.z);
bool FrustumError = false;
int zeroVectors = 0;
if (euler.x == 0)
zeroVectors++;
if (euler.y == 0)
zeroVectors++;
if (euler.z == 0)
zeroVectors++;
if (zeroVectors > 1) {
FrustumError = true;
}
if (!FrustumError) {
reflectionCamera.Render ();
reflectionCamera.transform.position = oldpos;
GL.invertCulling = false;
if (_ReflectionTexNameID == -1) {
_ReflectionTexNameID = Shader.PropertyToID (_ReflectionTexName);
}
mainRenderer.sharedMaterial.SetTexture (_ReflectionTexNameID, m_ReflectionTexture);
}
}
// Render refraction
if (mode >= WaterMode.Refractive) {
refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix;
// Setup oblique projection matrix so that near plane is our reflection
// plane. This way we clip everything below/above it for free.
Vector4 clipPlane = CameraSpacePlane (refractionCamera, pos, normal, -1.0f);
refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix (clipPlane);
refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer
refractionCamera.targetTexture = m_RefractionTexture;
refractionCamera.transform.position = cam.transform.position;
refractionCamera.transform.rotation = cam.transform.rotation;
bool FrustumError = false;
int zeroVectors = 0;
if (cam.transform.rotation.x == 0)
zeroVectors++;
if (cam.transform.rotation.y == 0)
zeroVectors++;
if (cam.transform.rotation.z == 0)
zeroVectors++;
if (zeroVectors > 1) {
FrustumError = true;
}
if (!FrustumError) {
refractionCamera.Render ();
if (_RefractionTexNameID == -1) {
_RefractionTexNameID = Shader.PropertyToID (_RefractionTexName);
}
mainRenderer.sharedMaterial.SetTexture (_RefractionTexName, m_RefractionTexture);
}
}
// Restore pixel light count
if (disablePixelLights) {
QualitySettings.pixelLightCount = oldPixelLightCount;
}
// Setup shader keywords based on water mode
switch (mode) {
case WaterMode.Simple:
Shader.EnableKeyword ("WATER_SIMPLE");
Shader.DisableKeyword ("WATER_REFLECTIVE");
Shader.DisableKeyword ("WATER_REFRACTIVE");
break;
case WaterMode.Reflective:
Shader.DisableKeyword ("WATER_SIMPLE");
Shader.EnableKeyword ("WATER_REFLECTIVE");
Shader.DisableKeyword ("WATER_REFRACTIVE");
break;
case WaterMode.Refractive:
Shader.DisableKeyword ("WATER_SIMPLE");
Shader.DisableKeyword ("WATER_REFLECTIVE");
Shader.EnableKeyword ("WATER_REFRACTIVE");
break;
}
s_InsideWater = false;
}
// Cleanup all the objects we possibly have created
void OnDisable ()
{
if (m_ReflectionTexture != null) {
DestroyImmediate (m_ReflectionTexture);
m_ReflectionTexture = null;
}
if (m_RefractionTexture != null) {
DestroyImmediate (m_RefractionTexture);
m_RefractionTexture = null;
}
foreach (var kvp in m_ReflectionCameras) {
DestroyImmediate ((kvp.Value).gameObject);
}
m_ReflectionCameras.Clear ();
foreach (var kvp in m_RefractionCameras) {
DestroyImmediate ((kvp.Value).gameObject);
}
m_RefractionCameras.Clear ();
}
bool mainRendererLocated;
bool sharedMaterialLocated;
Material mat;
void Start ()
{
mainRenderer = GetComponent<Renderer> ();
mainRendererLocated = mainRenderer != null;
if (mainRendererLocated) {
mat = mainRenderer.sharedMaterial;
sharedMaterialLocated = mat != null;
}
}
// This just sets up some matrices in the material; for really
// old cards to make water texture scroll.
void Update ()
{
if (!mainRendererLocated) {
return;
}
if (!sharedMaterialLocated) {
return;
}
if (!Application.isPlaying) {
if (!updateFXOnEditorEnabled) {
return;
}
} else {
if (!updateFXInGameEnabled) {
return;
}
}
if (WaveSpeedNameID == -1) {
WaveSpeedNameID = Shader.PropertyToID (WaveSpeedName);
}
Vector4 waveSpeed = mat.GetVector (WaveSpeedNameID);
if (_WaveScaleNameID == -1) {
_WaveScaleNameID = Shader.PropertyToID (_WaveScaleName);
}
float waveScale = mat.GetFloat (_WaveScaleNameID);
Vector4 waveScale4 = new Vector4 (waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f);
// Time since level load, and do intermediate calculations with doubles
double t = Time.timeSinceLevelLoad / 20.0;
Vector4 offsetClamped = new Vector4 (
(float)Math.IEEERemainder (waveSpeed.x * waveScale4.x * t, 1.0),
(float)Math.IEEERemainder (waveSpeed.y * waveScale4.y * t, 1.0),
(float)Math.IEEERemainder (waveSpeed.z * waveScale4.z * t, 1.0),
(float)Math.IEEERemainder (waveSpeed.w * waveScale4.w * t, 1.0)
);
if (_WaveOffsetNameID == -1) {
_WaveOffsetNameID = Shader.PropertyToID (_WaveOffsetName);
}
mat.SetVector (_WaveOffsetNameID, offsetClamped);
if (_WaveScale4NameID == -1) {
_WaveScale4NameID = Shader.PropertyToID (_WaveScale4Name);
}
mat.SetVector (_WaveScale4NameID, waveScale4);
}
void UpdateCameraModes (Camera src, Camera dest)
{
if (dest == null) {
return;
}
// set water camera to clear the same way as current camera
dest.clearFlags = src.clearFlags;
dest.backgroundColor = src.backgroundColor;
if (src.clearFlags == CameraClearFlags.Skybox) {
Skybox sky = src.GetComponent<Skybox> ();
Skybox mysky = dest.GetComponent<Skybox> ();
if (sky == null || sky.material == null) {
mysky.enabled = false;
} else {
mysky.enabled = true;
mysky.material = sky.material;
}
}
// update other values to match current camera.
// even if we are supplying custom camera&projection matrices,
// some of values are used elsewhere (e.g. skybox uses far plane)
dest.farClipPlane = src.farClipPlane;
dest.nearClipPlane = src.nearClipPlane;
dest.orthographic = src.orthographic;
dest.fieldOfView = src.fieldOfView;
dest.aspect = src.aspect;
dest.orthographicSize = src.orthographicSize;
}
// On-demand create any objects we need for water
void CreateWaterObjects (Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera)
{
WaterMode mode = GetWaterMode ();
reflectionCamera = null;
refractionCamera = null;
if (mode >= WaterMode.Reflective) {
// Reflection render texture
if (m_ReflectionTexture == null || m_OldReflectionTextureSize != textureSize) {
if (m_ReflectionTexture != null) {
DestroyImmediate (m_ReflectionTexture);
}
m_ReflectionTexture = new RenderTexture (textureSize, textureSize, 16);
m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID ();
m_ReflectionTexture.isPowerOfTwo = true;
m_ReflectionTexture.hideFlags = HideFlags.DontSave;
m_OldReflectionTextureSize = textureSize;
}
// Camera for reflection
m_ReflectionCameras.TryGetValue (currentCamera, out reflectionCamera);
if (reflectionCamera == null) { // catch both not-in-dictionary and in-dictionary-but-deleted-GO
GameObject go = new GameObject ("Water Refl Camera id" + GetInstanceID () + " for " + currentCamera.GetInstanceID (), typeof(Camera), typeof(Skybox));
reflectionCamera = go.GetComponent<Camera> ();
reflectionCamera.enabled = false;
reflectionCamera.transform.position = transform.position;
reflectionCamera.transform.rotation = transform.rotation;
reflectionCamera.gameObject.AddComponent<FlareLayer> ();
go.hideFlags = HideFlags.HideAndDontSave;
m_ReflectionCameras [currentCamera] = reflectionCamera;
}
}
if (mode >= WaterMode.Refractive) {
// Refraction render texture
if (m_RefractionTexture == null || m_OldRefractionTextureSize != textureSize) {
if (m_RefractionTexture != null) {
DestroyImmediate (m_RefractionTexture);
}
m_RefractionTexture = new RenderTexture (textureSize, textureSize, 16);
m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID ();
m_RefractionTexture.isPowerOfTwo = true;
m_RefractionTexture.hideFlags = HideFlags.DontSave;
m_OldRefractionTextureSize = textureSize;
}
// Camera for refraction
m_RefractionCameras.TryGetValue (currentCamera, out refractionCamera);
if (refractionCamera == null) { // catch both not-in-dictionary and in-dictionary-but-deleted-GO
GameObject go =
new GameObject ("Water Refr Camera id" + GetInstanceID () + " for " + currentCamera.GetInstanceID (),
typeof(Camera), typeof(Skybox));
refractionCamera = go.GetComponent<Camera> ();
refractionCamera.enabled = false;
refractionCamera.transform.position = transform.position;
refractionCamera.transform.rotation = transform.rotation;
refractionCamera.gameObject.AddComponent<FlareLayer> ();
go.hideFlags = HideFlags.HideAndDontSave;
m_RefractionCameras [currentCamera] = refractionCamera;
}
}
}
WaterMode GetWaterMode ()
{
if (m_HardwareWaterSupport < waterMode) {
return m_HardwareWaterSupport;
}
return waterMode;
}
WaterMode FindHardwareWaterSupport ()
{
mainRenderer = GetComponent<Renderer> ();
if (mainRenderer == null) {
return WaterMode.Simple;
}
mat = mainRenderer.sharedMaterial;
if (mat == null) {
return WaterMode.Simple;
}
string mode = mat.GetTag ("WATERMODE", false);
if (mode.Equals ("Refractive")) {
return WaterMode.Refractive;
}
if (mode.Equals ("Reflective")) {
return WaterMode.Reflective;
}
return WaterMode.Simple;
}
// Given position/normal of the plane, calculates plane in camera space.
Vector4 CameraSpacePlane (Camera cam, Vector3 pos, Vector3 normal, float sideSign)
{
Vector3 offsetPos = pos + clipPlaneOffset * normal;
Matrix4x4 m = cam.worldToCameraMatrix;
Vector3 cpos = m.MultiplyPoint (offsetPos);
Vector3 cnormal = sideSign * m.MultiplyVector (normal).normalized;
return new Vector4 (cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot (cpos, cnormal));
}
// Calculates reflection matrix around the given plane
static void CalculateReflectionMatrix (ref Matrix4x4 reflectionMat, Vector4 plane)
{
reflectionMat.m00 = (1F - 2F * plane [0] * plane [0]);
reflectionMat.m01 = (-2F * plane [0] * plane [1]);
reflectionMat.m02 = (-2F * plane [0] * plane [2]);
reflectionMat.m03 = (-2F * plane [3] * plane [0]);
reflectionMat.m10 = (-2F * plane [1] * plane [0]);
reflectionMat.m11 = (1F - 2F * plane [1] * plane [1]);
reflectionMat.m12 = (-2F * plane [1] * plane [2]);
reflectionMat.m13 = (-2F * plane [3] * plane [1]);
reflectionMat.m20 = (-2F * plane [2] * plane [0]);
reflectionMat.m21 = (-2F * plane [2] * plane [1]);
reflectionMat.m22 = (1F - 2F * plane [2] * plane [2]);
reflectionMat.m23 = (-2F * plane [3] * plane [2]);
reflectionMat.m30 = 0F;
reflectionMat.m31 = 0F;
reflectionMat.m32 = 0F;
reflectionMat.m33 = 1F;
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 00ac975299a9ab24f898dc814c9263bb
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/WaterFX.cs
uploadId: 889948

View File

@@ -0,0 +1,448 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
[RequireComponent (typeof (BoxCollider))]
[RequireComponent (typeof (MeshFilter))]
public class WaterVolume : waterSurfaceSystem
{
[Header ("Main Settings")]
[Space]
public float waterHeight = 5;
public float density = 1f;
public int rows = 10;
public int columns = 10;
public float quadSegmentSize = 1f;
public bool useCustomGravityForce = true;
public Vector3 gravityForce = new Vector3 (0, -9.8f, 0);
[Space]
[Header ("Object Detection Settings")]
[Space]
public LayerMask objectLayermask;
public bool checkObjectByTag;
public List<string> tagListToCheck = new List<string> ();
public bool checkForFloatingObjectSocketEnabled = true;
[Space]
[Header ("Gizmo Settings")]
[Space]
public bool showDebugPrint;
public bool showGizmo;
private Mesh mesh;
private Vector3 [] meshLocalVertices;
private Vector3 [] meshWorldVertices;
bool meshLocated;
BoxCollider mainBoxCollider;
public List<GameObject> objectsOnWaterList = new List<GameObject> ();
public float Density
{
get
{
return density;
}
}
public int Rows
{
get
{
return rows;
}
}
public int Columns
{
get
{
return columns;
}
}
public float QuadSegmentSize
{
get
{
return quadSegmentSize;
}
}
public Mesh Mesh
{
get
{
if (!meshLocated) {
if (mesh == null) {
mesh = GetComponent<MeshFilter> ().mesh;
}
meshLocated = mesh != null;
}
return mesh;
}
}
protected virtual void Awake ()
{
CacheMeshVertices ();
}
protected virtual void Update ()
{
CacheMeshVertices ();
}
public Vector3 [] GetSurroundingTrianglePolygon (Vector3 worldPoint)
{
Vector3 localPoint = transform.InverseTransformPoint (worldPoint);
int x = Mathf.CeilToInt (localPoint.x / QuadSegmentSize);
int z = Mathf.CeilToInt (localPoint.z / QuadSegmentSize);
if (x <= 0 || z <= 0 || x >= (Columns + 1) || z >= (Rows + 1)) {
return null;
}
Vector3 [] trianglePolygon = new Vector3 [3];
int index1 = GetIndex (z, x);
int index2 = GetIndex (z - 1, x - 1);
int meshWorldVerticesLength = meshWorldVertices.Length;
if (index1 < meshWorldVerticesLength && index2 < meshWorldVerticesLength) {
if ((worldPoint - meshWorldVertices [index1]).sqrMagnitude <
((worldPoint - meshWorldVertices [index2]).sqrMagnitude)) {
trianglePolygon [0] = meshWorldVertices [index1];
} else {
trianglePolygon [0] = meshWorldVertices [index2];
}
}
int index3 = GetIndex (z - 1, x);
int index4 = GetIndex (z, x - 1);
if (index3 < meshWorldVerticesLength && index4 < meshWorldVerticesLength) {
trianglePolygon [1] = meshWorldVertices [index3];
trianglePolygon [2] = meshWorldVertices [index4];
}
return trianglePolygon;
}
public Vector3 [] GetClosestPointsOnWaterSurface (Vector3 worldPoint, int pointsCount)
{
MinHeap<Vector3> allPoints = new MinHeap<Vector3> (new Vector3HorizontalDistanceComparer (worldPoint));
int meshWorldVerticesLength = meshWorldVertices.Length;
for (int i = 0; i < meshWorldVerticesLength; i++) {
allPoints.Add (meshWorldVertices [i]);
}
Vector3 [] closestPoints = new Vector3 [pointsCount];
int closestPointsLength = closestPoints.Length;
for (int i = 0; i < closestPointsLength; i++) {
closestPoints [i] = allPoints.Remove ();
}
return closestPoints;
}
public override Vector3 GetSurfaceNormal (Vector3 worldPoint)
{
Vector3 [] meshPolygon = GetSurroundingTrianglePolygon (worldPoint);
if (meshPolygon != null) {
Vector3 meshPolygon0 = meshPolygon [0];
Vector3 planeV1 = meshPolygon [1] - meshPolygon0;
Vector3 planeV2 = meshPolygon [2] - meshPolygon0;
Vector3 planeNormal = Vector3.Cross (planeV1, planeV2).normalized;
if (planeNormal.y < 0f) {
planeNormal = -1f * planeNormal;
}
return planeNormal;
}
return transform.up;
}
public override float GetWaterLevel (Vector3 worldPoint)
{
Vector3 [] meshPolygon = GetSurroundingTrianglePolygon (worldPoint);
if (meshPolygon != null) {
Vector3 meshPolygon0 = meshPolygon [0];
Vector3 planeV1 = meshPolygon [1] - meshPolygon0;
Vector3 planeV2 = meshPolygon [2] - meshPolygon0;
Vector3 planeNormal = Vector3.Cross (planeV1, planeV2).normalized;
if (planeNormal.y < 0f) {
planeNormal = -1f * planeNormal;
}
// Plane equation
float yOnWaterSurface = (-(worldPoint.x * planeNormal.x) - (worldPoint.z * planeNormal.z)
+ Vector3.Dot (meshPolygon0, planeNormal)) / planeNormal.y;
//Vector3 pointOnWaterSurface = new Vector3(point.x, yOnWaterSurface, point.z);
//DebugUtils.DrawPoint(pointOnWaterSurface, Color.magenta);
return yOnWaterSurface;
}
return transform.position.y;
}
public bool IsPointUnderWater (Vector3 worldPoint)
{
return GetWaterLevel (worldPoint) - worldPoint.y > 0f;
}
private int GetIndex (int row, int column)
{
return row * (Columns + 1) + column;
}
private void CacheMeshVertices ()
{
meshLocalVertices = Mesh.vertices;
meshWorldVertices = ConvertPointsToWorldSpace (meshLocalVertices);
}
private Vector3 [] ConvertPointsToWorldSpace (Vector3 [] localPoints)
{
int localPointsLength = localPoints.Length;
Vector3 [] worldPoints = new Vector3 [localPointsLength];
for (int i = 0; i < localPointsLength; i++) {
worldPoints [i] = transform.TransformPoint (localPoints [i]);
}
return worldPoints;
}
private class Vector3HorizontalDistanceComparer : IComparer<Vector3>
{
private Vector3 distanceToVector;
public Vector3HorizontalDistanceComparer (Vector3 distanceTo)
{
distanceToVector = distanceTo;
}
public int Compare (Vector3 v1, Vector3 v2)
{
v1.y = 0;
v2.y = 0;
float v1Distance = (v1 - distanceToVector).sqrMagnitude;
float v2Distance = (v2 - distanceToVector).sqrMagnitude;
if (v1Distance < v2Distance) {
return -1;
} else if (v1Distance > v2Distance) {
return 1;
} else {
return 0;
}
}
}
public override Vector3 getGravityForce ()
{
if (useCustomGravityForce) {
return gravityForce;
} else {
return Physics.gravity;
}
}
public override float getDensity ()
{
return density;
}
public void setNewGravityForce (Vector3 newValues)
{
gravityForce = newValues;
for (int i = 0; i < objectsOnWaterList.Count; i++) {
FloatingObject currentFloatingObject = objectsOnWaterList [i].GetComponent<FloatingObject> ();
if (currentFloatingObject != null) {
currentFloatingObject.setNewGravityForce (gravityForce);
}
}
}
public void setUseCustomGravityForceState (bool state)
{
useCustomGravityForce = state;
}
void OnTriggerEnter (Collider col)
{
checkTriggerInfo (col, true);
}
void OnTriggerExit (Collider col)
{
checkTriggerInfo (col, false);
}
public void checkTriggerInfo (Collider col, bool isEnter)
{
bool checkResult = true;
if ((1 << col.gameObject.layer & objectLayermask.value) != 1 << col.gameObject.layer) {
checkResult = false;
}
if (!checkResult) {
if (checkObjectByTag) {
if (tagListToCheck.Contains (col.gameObject.tag)) {
checkResult = true;
} else {
checkResult = false;
}
}
}
if (!checkResult) {
if (checkForFloatingObjectSocketEnabled) {
FloatingObjectSocket currentFloatingObjectSocket = col.gameObject.GetComponent<FloatingObjectSocket> ();
if (currentFloatingObjectSocket != null) {
checkResult = true;
}
}
}
if (!checkResult) {
return;
}
FloatingObject currentFloatingObject = col.gameObject.GetComponent<FloatingObject> ();
if (currentFloatingObject == null) {
FloatingObjectSocket currentFloatingObjectSocket = col.gameObject.GetComponent<FloatingObjectSocket> ();
if (currentFloatingObjectSocket != null) {
currentFloatingObject = currentFloatingObjectSocket.getFloatingObject ();
}
}
if (currentFloatingObject != null) {
if (showDebugPrint) {
print ("setting floating object state " + currentFloatingObject.name + " " + isEnter);
}
currentFloatingObject.setWaterVolumeState (this, isEnter);
if (isEnter) {
if (!objectsOnWaterList.Contains (currentFloatingObject.gameObject)) {
objectsOnWaterList.Add (currentFloatingObject.gameObject);
}
} else {
if (objectsOnWaterList.Contains (currentFloatingObject.gameObject)) {
objectsOnWaterList.Remove (currentFloatingObject.gameObject);
}
}
for (int i = objectsOnWaterList.Count - 1; i >= 0; i--) {
if (objectsOnWaterList [i] == null) {
objectsOnWaterList.RemoveAt (i);
}
}
}
}
public override float CalculateVolume_Mesh (Mesh mesh, Transform trans)
{
return MathfUtils.CalculateVolume_Mesh (mesh, trans);
}
public override bool IsPointInsideCollider (Vector3 point, Collider collider, ref Bounds colliderBounds)
{
return ColliderUtils.IsPointInsideCollider (point, collider, ref colliderBounds);
}
//Draw gizmos
#if UNITY_EDITOR
void OnDrawGizmos ()
{
if (!showGizmo) {
return;
}
if (GKC_Utils.isCurrentSelectionActiveGameObject (gameObject)) {
DrawGizmos ();
}
}
void OnDrawGizmosSelected ()
{
DrawGizmos ();
}
void DrawGizmos ()
{
if (showGizmo) {
if (!Application.isPlaying) {
Gizmos.color = Color.green;
Gizmos.matrix = transform.localToWorldMatrix;
if (mainBoxCollider == null) {
mainBoxCollider = GetComponent<BoxCollider> ();
}
if (mainBoxCollider != null) {
Gizmos.DrawWireCube (mainBoxCollider.center, mainBoxCollider.size);
Gizmos.color = Color.cyan - new Color (0f, 0f, 0f, 0.75f);
Gizmos.matrix = transform.localToWorldMatrix;
Gizmos.DrawCube (mainBoxCollider.center - 0.01f * Vector3.up, mainBoxCollider.size);
Gizmos.color = Color.cyan - new Color (0f, 0f, 0f, 0.5f);
Gizmos.DrawWireCube (mainBoxCollider.center, mainBoxCollider.size);
Gizmos.matrix = Matrix4x4.identity;
}
}
}
}
#endif
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: ef62fa15ac390d4488541838f936956e
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/WaterVolume.cs
uploadId: 889948

View File

@@ -0,0 +1,93 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy
{
public class WaterWaves : MonoBehaviour
{
[Header ("Main Settings")]
[Space]
public bool wavesEnabled = true;
[SerializeField]
private float speed = 1f;
[SerializeField]
private float height = 0.2f;
[SerializeField]
private float noiseWalk = 0.5f;
[SerializeField]
private float noiseStrength = 0.1f;
private Mesh mesh;
private Vector3[] baseVertices;
private Vector3[] vertices;
int verticesLength;
Vector3 currentBaseVertices;
float currentLocalScaleY;
float currentSize;
protected virtual void Awake ()
{
mesh = GetComponent<MeshFilter> ().mesh;
baseVertices = mesh.vertices;
vertices = new Vector3[baseVertices.Length];
}
protected virtual void Start ()
{
ResizeBoxCollider ();
verticesLength = vertices.Length;
currentLocalScaleY = transform.localScale.y;
currentSize = (height / currentLocalScaleY);
}
protected virtual void Update ()
{
if (wavesEnabled) {
for (var i = 0; i < verticesLength; i++) {
currentBaseVertices = baseVertices [i];
var vertex = currentBaseVertices;
vertex.y +=
Mathf.Sin (Time.time * speed + currentBaseVertices.x + currentBaseVertices.y + currentBaseVertices.z) *
currentSize;
vertex.y +=
Mathf.PerlinNoise (currentBaseVertices.x + noiseWalk, currentBaseVertices.y /*+ Mathf.Sin(Time.time * 0.1f)*/) *
noiseStrength;
vertices [i] = vertex;
}
mesh.vertices = vertices;
mesh.RecalculateNormals ();
}
}
private void ResizeBoxCollider ()
{
var boxCollider = GetComponent<BoxCollider> ();
if (boxCollider != null) {
Vector3 center = boxCollider.center;
center.y = boxCollider.size.y / -2f;
center.y += (height + noiseStrength) / transform.localScale.y;
boxCollider.center = center;
}
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: afcec5aaca573294e986610aa411d1e5
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Core/WaterWaves.cs
uploadId: 889948

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 11632efdf9d827b4aa5d4604dd9b019a
folderAsset: yes
timeCreated: 1673260982
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,90 @@
using UnityEngine;
namespace NaughtyWaterBuoyancy.Editor
{
public class WaterMeshGenerator
{
private static int rows;
private static int columns;
private static float quadSegmentSize;
public static Mesh GenerateMesh(int _rows, int _columns, float _quadSegmentSize)
{
if (_rows < 0f || _columns < 0 || _quadSegmentSize < 0f)
{
throw new System.ArgumentException("Invalid water mesh data");
}
rows = _rows + 1; // There are 2 rows between 3 points, so we need to add 1
columns = _columns + 1; // Same here
quadSegmentSize = _quadSegmentSize;
var mesh = new Mesh();
mesh.name = "Water Mesh";
MeshData meshData = new MeshData();
meshData.Vertices = new Vector3[rows * columns];
meshData.Normals = new Vector3[rows * columns];
meshData.UVs = new Vector2[rows * columns];
meshData.TriangleIndices = new int[rows * columns * 6];
int triangleIndex = 0;
for (int r = 0; r < rows; r++)
{
for (int c = 0; c < columns; c++)
{
int index = GetIndex(r, c);
// Set vertices, normals and UVs
meshData.Vertices[index] = new Vector3(c * quadSegmentSize, 0f, r * quadSegmentSize);
meshData.Normals[index] = Vector3.up;
meshData.UVs[index] = new Vector2((float)c / columns, (float)r / rows);
// Set triangles
if (r < rows - 1 && c < columns - 1)
{
meshData.TriangleIndices[triangleIndex + 0] = GetIndex(r, c);
meshData.TriangleIndices[triangleIndex + 1] = GetIndex(r + 1, c);
meshData.TriangleIndices[triangleIndex + 2] = GetIndex(r, c + 1);
meshData.TriangleIndices[triangleIndex + 3] = GetIndex(r + 1, c);
meshData.TriangleIndices[triangleIndex + 4] = GetIndex(r + 1, c + 1);
meshData.TriangleIndices[triangleIndex + 5] = GetIndex(r, c + 1);
triangleIndex += 6;
}
}
}
mesh.vertices = meshData.Vertices;
mesh.normals = meshData.Normals;
mesh.uv = meshData.UVs;
mesh.triangles = meshData.TriangleIndices;
return mesh;
}
private static int GetIndex(int row, int column)
{
return row * columns + column;
}
private static int GetRow(int vertexIndex)
{
return vertexIndex / columns;
}
private static int GetColumn(int vertexIndex)
{
return vertexIndex % columns;
}
private struct MeshData
{
public Vector3[] Vertices { get; set; }
public Vector3[] Normals { get; set; }
public Vector2[] UVs { get; set; }
public int[] TriangleIndices { get; set; }
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: 1f16f89f10f6e1a4e933fc2824f43785
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Editor/WaterMeshGenerator.cs
uploadId: 889948

View File

@@ -0,0 +1,219 @@
using UnityEditor;
using UnityEngine;
namespace NaughtyWaterBuoyancy.Editor
{
[CustomEditor (typeof(WaterVolume))]
public class WaterVolumeEditor : UnityEditor.Editor
{
private SerializedProperty waterHeight;
private WaterVolume waterVolumeTarget;
private SerializedProperty density;
private SerializedProperty rows;
private SerializedProperty columns;
private SerializedProperty quadSegmentSize;
private SerializedProperty useCustomGravityForce;
private SerializedProperty gravityForce;
private SerializedProperty objectLayermask;
private SerializedProperty checkObjectByTag;
private SerializedProperty tagListToCheck;
private SerializedProperty checkForFloatingObjectSocketEnabled;
SerializedProperty showDebugPrint;
SerializedProperty showGizmo;
WaterVolume manager;
// [MenuItem ("NaughtyWaterBouyancy/Create Water Mesh")]
// private static void CreateMesh ()
// {
// Mesh mesh = WaterMeshGenerator.GenerateMesh (5, 5, 1f);
// AssetDatabase.CreateAsset (mesh, "Assets/NaughtyWaterBuoyancy/Models/Water Mesh.asset");
// }
protected virtual void OnEnable ()
{
this.waterVolumeTarget = (WaterVolume)this.target;
this.waterHeight = this.serializedObject.FindProperty ("waterHeight");
this.density = this.serializedObject.FindProperty ("density");
this.rows = this.serializedObject.FindProperty ("rows");
this.columns = this.serializedObject.FindProperty ("columns");
this.quadSegmentSize = this.serializedObject.FindProperty ("quadSegmentSize");
this.useCustomGravityForce = this.serializedObject.FindProperty ("useCustomGravityForce");
this.gravityForce = this.serializedObject.FindProperty ("gravityForce");
this.objectLayermask = this.serializedObject.FindProperty ("objectLayermask");
this.checkObjectByTag = this.serializedObject.FindProperty ("checkObjectByTag");
this.tagListToCheck = this.serializedObject.FindProperty ("tagListToCheck");
this.checkForFloatingObjectSocketEnabled = this.serializedObject.FindProperty ("checkForFloatingObjectSocketEnabled");
this.showDebugPrint = this.serializedObject.FindProperty ("showDebugPrint");
this.showGizmo = this.serializedObject.FindProperty ("showGizmo");
Undo.undoRedoPerformed += this.OnUndoRedoPerformed;
manager = (WaterVolume)target;
}
protected virtual void OnDisable ()
{
Undo.undoRedoPerformed -= this.OnUndoRedoPerformed;
}
public override void OnInspectorGUI ()
{
this.serializedObject.Update ();
EditorGUILayout.Space ();
EditorGUI.BeginChangeCheck ();
EditorGUILayout.PropertyField (this.waterHeight);
EditorGUILayout.PropertyField (this.rows);
EditorGUILayout.PropertyField (this.columns);
EditorGUILayout.PropertyField (this.quadSegmentSize);
EditorGUILayout.PropertyField (this.useCustomGravityForce);
EditorGUILayout.PropertyField (this.gravityForce);
if (EditorGUI.EndChangeCheck ()) {
this.rows.intValue = Mathf.Max (1, this.rows.intValue);
this.columns.intValue = Mathf.Max (1, this.columns.intValue);
this.quadSegmentSize.floatValue = Mathf.Max (0f, this.quadSegmentSize.floatValue);
if (!Application.isPlaying) {
this.UpdateMesh (this.rows.intValue, this.columns.intValue, this.quadSegmentSize.floatValue);
this.UpdateBoxCollider (this.rows.intValue, this.columns.intValue, this.quadSegmentSize.floatValue);
}
}
EditorGUILayout.PropertyField (this.density);
EditorGUILayout.Space ();
EditorGUILayout.PropertyField (this.objectLayermask);
EditorGUILayout.PropertyField (this.checkObjectByTag);
if (this.checkObjectByTag.boolValue) {
EditorGUILayout.Space ();
showSimpleList (this.tagListToCheck);
}
EditorGUILayout.PropertyField (this.checkForFloatingObjectSocketEnabled);
EditorGUILayout.Space ();
EditorGUILayout.PropertyField (this.showDebugPrint);
EditorGUILayout.PropertyField (this.showGizmo);
EditorGUILayout.Space ();
EditorGUILayout.Space ();
if (GUILayout.Button ("Update System")) {
if (!Application.isPlaying) {
this.UpdateMesh (this.rows.intValue, this.columns.intValue, this.quadSegmentSize.floatValue);
this.UpdateBoxCollider (this.rows.intValue, this.columns.intValue, this.quadSegmentSize.floatValue);
}
}
this.serializedObject.ApplyModifiedProperties ();
}
private void UpdateMesh (int rows, int columns, float quadSegmentSize)
{
MeshFilter meshFilter = this.waterVolumeTarget.GetComponent<MeshFilter> ();
Mesh oldMesh = meshFilter.sharedMesh;
Mesh newMesh = WaterMeshGenerator.GenerateMesh (rows, columns, quadSegmentSize);
newMesh.name = "Water Mesh Instance";
meshFilter.sharedMesh = newMesh;
EditorUtility.SetDirty (meshFilter);
if (oldMesh != null && !AssetDatabase.Contains (oldMesh)) {
DestroyImmediate (oldMesh);
}
}
private void UpdateBoxCollider (int rows, int columns, float quadSegmentSize)
{
var boxCollider = this.waterVolumeTarget.GetComponent<BoxCollider> ();
if (boxCollider != null) {
Vector3 size = new Vector3 (columns * quadSegmentSize, waterHeight.floatValue, rows * quadSegmentSize);
boxCollider.size = size;
Vector3 center = size / 2f;
center.y *= -1f;
boxCollider.center = center;
EditorUtility.SetDirty (boxCollider);
}
}
private void OnUndoRedoPerformed ()
{
this.UpdateMesh (this.waterVolumeTarget.Rows, this.waterVolumeTarget.Columns, this.waterVolumeTarget.QuadSegmentSize);
this.UpdateBoxCollider (this.waterVolumeTarget.Rows, this.waterVolumeTarget.Columns, this.waterVolumeTarget.QuadSegmentSize);
}
void showSimpleList (SerializedProperty list)
{
EditorGUILayout.Space ();
if (GUILayout.Button ("Show/Hide " + list.displayName)) {
list.isExpanded = !list.isExpanded;
}
EditorGUILayout.Space ();
if (list.isExpanded) {
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("Add")) {
list.arraySize++;
}
if (GUILayout.Button ("Clear")) {
list.arraySize = 0;
}
GUILayout.EndHorizontal ();
EditorGUILayout.Space ();
for (int i = 0; i < list.arraySize; i++) {
GUILayout.BeginHorizontal ();
if (i < list.arraySize && i >= 0) {
EditorGUILayout.PropertyField (list.GetArrayElementAtIndex (i), new GUIContent ("", null, ""), false);
}
GUILayout.BeginHorizontal ();
if (GUILayout.Button ("x")) {
list.DeleteArrayElementAtIndex (i);
return;
}
if (GUILayout.Button ("v")) {
if (i >= 0) {
list.MoveArrayElement (i, i + 1);
}
}
if (GUILayout.Button ("^")) {
if (i < list.arraySize) {
list.MoveArrayElement (i, i - 1);
}
}
GUILayout.EndHorizontal ();
GUILayout.EndHorizontal ();
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
fileFormatVersion: 2
guid: c2872cce0a936bb4ba5f6411a4abf1b5
timeCreated: 1673260982
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 40995
packageName: Game Kit Controller - Shooter Melee Adventure FPS TPS Creator 3D +
2.5D
packageVersion: 3.77h
assetPath: Assets/Game Kit Controller/Integrations/NaughtyWaterBuoyancy/Scripts/Editor/WaterVolumeEditor.cs
uploadId: 889948