add some extra assets FX and SFX
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89b3d095043131f4c9793444b6d3e83e
|
||||
folderAsset: yes
|
||||
timeCreated: 1673260982
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5832314657fda4c4abe73d1069b14b16
|
||||
folderAsset: yes
|
||||
timeCreated: 1673260982
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e6de35f7fd668f43b04f03ab20f61dd
|
||||
folderAsset: yes
|
||||
timeCreated: 1673260982
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 11632efdf9d827b4aa5d4604dd9b019a
|
||||
folderAsset: yes
|
||||
timeCreated: 1673260982
|
||||
licenseType: Store
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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 ();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user