444 lines
9.7 KiB
C#
444 lines
9.7 KiB
C#
using UnityEngine;
|
|
|
|
public class RealWaterCollisionNode : MonoBehaviour
|
|
{
|
|
public enum Objecttype
|
|
{
|
|
RigidBody = 0,
|
|
CharacterController = 1
|
|
}
|
|
|
|
[HideInInspector]
|
|
public float XCoord;
|
|
|
|
[HideInInspector]
|
|
public float YCoord;
|
|
|
|
[HideInInspector]
|
|
public bool Colliding;
|
|
|
|
[HideInInspector]
|
|
public int HitPlaneID;
|
|
|
|
[HideInInspector]
|
|
public bool CheckWaterCollision = true;
|
|
|
|
public GameObject ParentCollider;
|
|
|
|
[Tooltip("Is the collider a Rigidbody or a Character controller?")]
|
|
public Objecttype ObjectType;
|
|
|
|
[Tooltip("Force Multiplier")]
|
|
[Range(0.01f, 1f)]
|
|
public float InputForce = 1f;
|
|
|
|
[Tooltip("Only check for collisions if the collider velocity exceeds this value")]
|
|
public float VelocityLimit = 0.05f;
|
|
|
|
[Tooltip("Raycast origin position offset.")]
|
|
public Vector3 RaycastOffset;
|
|
|
|
public float RaycastLength = 1f;
|
|
|
|
[Tooltip("Extrapolates between input points, allows for smoother more consistent input.")]
|
|
public bool ExtrapolateInput = true;
|
|
|
|
[Tooltip("Disables the visibility check so water collider will always check for collisions even when not visible.")]
|
|
public bool FirstPersonMode;
|
|
|
|
[Tooltip("Enables collision logging and ray drawing in the inspector. Also removes the velocity limitation.Very useful for Setup.")]
|
|
public bool DebugMode;
|
|
|
|
[HideInInspector]
|
|
public float collisionCheckFrequency = 60f;
|
|
|
|
private bool IsCharController;
|
|
|
|
private bool IsRigidbody;
|
|
|
|
private CharacterController controller;
|
|
|
|
private RaycastHit Hit;
|
|
|
|
private int BaseForce = 18000000;
|
|
|
|
[HideInInspector]
|
|
public bool Visible = true;
|
|
|
|
private bool FirstPoint = true;
|
|
|
|
private bool FirstClick = true;
|
|
|
|
private int x1;
|
|
|
|
private int x2;
|
|
|
|
private int y1;
|
|
|
|
private int y2;
|
|
|
|
private int Plane1;
|
|
|
|
private int Plane2;
|
|
|
|
public static bool Reseting;
|
|
|
|
private int deltax;
|
|
|
|
private int deltay;
|
|
|
|
private int xinc1;
|
|
|
|
private int xinc2;
|
|
|
|
private int yinc1;
|
|
|
|
private int yinc2;
|
|
|
|
private int denominator;
|
|
|
|
private int numerator;
|
|
|
|
private int numadd;
|
|
|
|
private int NumberOfPoints;
|
|
|
|
private float ZPositionCurrent;
|
|
|
|
private float XPositionCurrent;
|
|
|
|
private float ZPositionPrevious;
|
|
|
|
private float XPositionPrevious;
|
|
|
|
private bool FirstRun = true;
|
|
|
|
private void Start()
|
|
{
|
|
switch (ObjectType)
|
|
{
|
|
case Objecttype.CharacterController:
|
|
IsCharController = true;
|
|
controller = ParentCollider.GetComponent<CharacterController>();
|
|
break;
|
|
case Objecttype.RigidBody:
|
|
IsRigidbody = true;
|
|
break;
|
|
}
|
|
if (DebugMode)
|
|
{
|
|
VelocityLimit = -1f;
|
|
}
|
|
if (!FirstPersonMode && !DebugMode)
|
|
{
|
|
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
|
|
}
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (Reseting)
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
ZPositionCurrent = ParentCollider.gameObject.transform.position.z;
|
|
XPositionCurrent = ParentCollider.gameObject.transform.position.x;
|
|
}
|
|
|
|
private void PositionCheck1()
|
|
{
|
|
ZPositionPrevious = Mathf.Round(base.transform.position.z * 10f) / 10f;
|
|
XPositionPrevious = Mathf.Round(base.transform.position.x * 10f) / 10f;
|
|
Invoke("PositionCheck2", 1f);
|
|
}
|
|
|
|
private void PositionCheck2()
|
|
{
|
|
ZPositionCurrent = Mathf.Round(base.transform.position.z * 10f) / 10f;
|
|
XPositionCurrent = Mathf.Round(base.transform.position.x * 10f) / 10f;
|
|
if (ZPositionCurrent == ZPositionPrevious && XPositionCurrent == XPositionPrevious)
|
|
{
|
|
CheckWaterCollision = false;
|
|
}
|
|
else
|
|
{
|
|
CheckWaterCollision = true;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
CancelInvoke();
|
|
RealWaterSpeedManager realWaterSpeedManager = Object.FindObjectOfType(typeof(RealWaterSpeedManager)) as RealWaterSpeedManager;
|
|
if (realWaterSpeedManager != null)
|
|
{
|
|
realWaterSpeedManager.FindCollisionNodes();
|
|
}
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (!FirstRun)
|
|
{
|
|
RealWaterSpeedManager realWaterSpeedManager = Object.FindObjectOfType(typeof(RealWaterSpeedManager)) as RealWaterSpeedManager;
|
|
if (realWaterSpeedManager != null)
|
|
{
|
|
realWaterSpeedManager.FindCollisionNodes();
|
|
}
|
|
if (!FirstPersonMode && !DebugMode)
|
|
{
|
|
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
|
|
}
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
}
|
|
else
|
|
{
|
|
FirstRun = false;
|
|
}
|
|
}
|
|
|
|
private void VisibilityCheck()
|
|
{
|
|
if (!ParentCollider.GetComponent<Renderer>().isVisible && !DebugMode)
|
|
{
|
|
CancelInvoke("PositionCheck1");
|
|
CancelInvoke("CheckForCollisions");
|
|
Visible = false;
|
|
}
|
|
else if (!Visible && ParentCollider.GetComponent<Renderer>().isVisible)
|
|
{
|
|
InvokeRepeating("CheckForCollisions", 0.005f, 1f / collisionCheckFrequency);
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
FirstClick = true;
|
|
Visible = true;
|
|
}
|
|
}
|
|
|
|
public void CheckForCollisions()
|
|
{
|
|
if (CheckWaterCollision)
|
|
{
|
|
if (IsRigidbody)
|
|
{
|
|
if (Physics.Raycast(base.transform.position + RaycastOffset, Vector3.down, out Hit, RaycastLength))
|
|
{
|
|
if (DebugMode)
|
|
{
|
|
MonoBehaviour.print(Hit.collider.gameObject.name);
|
|
}
|
|
if (Hit.collider.gameObject.name == "RealWater Plane")
|
|
{
|
|
if (ParentCollider.GetComponent<Rigidbody>().velocity.magnitude > VelocityLimit)
|
|
{
|
|
XCoord = Hit.textureCoord.x;
|
|
YCoord = Hit.textureCoord.y;
|
|
int rows = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetRows();
|
|
int cols = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetCols();
|
|
int bR = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetBR();
|
|
float num = YCoord * ((float)rows + 1f);
|
|
float num2 = XCoord * ((float)cols + 1f);
|
|
if ((int)num2 > bR + 1 && (int)num2 < cols - bR + 1 && (int)num < rows - (bR + 2) && (int)num > bR + 1)
|
|
{
|
|
if (ExtrapolateInput)
|
|
{
|
|
if (!FirstClick)
|
|
{
|
|
if (FirstPoint)
|
|
{
|
|
x1 = (int)num;
|
|
y1 = (int)num2;
|
|
Plane1 = Hit.collider.GetInstanceID();
|
|
}
|
|
else
|
|
{
|
|
x2 = (int)num;
|
|
y2 = (int)num2;
|
|
Plane2 = Hit.collider.GetInstanceID();
|
|
}
|
|
if (Plane1 == Plane2)
|
|
{
|
|
BresenhamLineAlgorithm(x1, x2, y1, y2);
|
|
}
|
|
FirstPoint = !FirstPoint;
|
|
}
|
|
else
|
|
{
|
|
x1 = (int)num;
|
|
y1 = (int)num2;
|
|
x2 = (int)num;
|
|
y2 = (int)num2;
|
|
FirstClick = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Hit.collider.gameObject.GetComponent<RealWaterInterface>().DisturbBufferAt((int)num, (int)num2, (int)(18000000f * InputForce), ambient: false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
else if (IsCharController)
|
|
{
|
|
if (Physics.Raycast(base.transform.position + RaycastOffset, Vector3.down, out Hit, RaycastLength))
|
|
{
|
|
if (DebugMode)
|
|
{
|
|
MonoBehaviour.print(Hit.collider.gameObject.name);
|
|
}
|
|
if (Hit.collider.gameObject.name == "RealWater Plane")
|
|
{
|
|
if (controller.velocity.magnitude > VelocityLimit)
|
|
{
|
|
XCoord = Hit.textureCoord.x;
|
|
YCoord = Hit.textureCoord.y;
|
|
int rows2 = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetRows();
|
|
int cols2 = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetCols();
|
|
int bR2 = Hit.collider.gameObject.GetComponent<RealWaterInterface>().GetBR();
|
|
float num3 = YCoord * ((float)rows2 + 1f);
|
|
float num4 = XCoord * ((float)cols2 + 1f);
|
|
if ((int)num4 > bR2 + 1 && (int)num4 < cols2 - bR2 + 1 && (int)num3 < rows2 - (bR2 + 2) && (int)num3 > bR2 + 1)
|
|
{
|
|
if (ExtrapolateInput)
|
|
{
|
|
if (!FirstClick)
|
|
{
|
|
if (FirstPoint)
|
|
{
|
|
x1 = (int)num3;
|
|
y1 = (int)num4;
|
|
Plane1 = Hit.collider.GetInstanceID();
|
|
}
|
|
else
|
|
{
|
|
x2 = (int)num3;
|
|
y2 = (int)num4;
|
|
Plane2 = Hit.collider.GetInstanceID();
|
|
}
|
|
if (Plane1 == Plane2)
|
|
{
|
|
BresenhamLineAlgorithm(x1, x2, y1, y2);
|
|
}
|
|
FirstPoint = !FirstPoint;
|
|
}
|
|
else
|
|
{
|
|
x1 = (int)num3;
|
|
y1 = (int)num4;
|
|
x2 = (int)num3;
|
|
y2 = (int)num4;
|
|
FirstClick = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Hit.collider.gameObject.GetComponent<RealWaterInterface>().DisturbBufferAt((int)num3, (int)num4, (int)(18000000f * InputForce), ambient: false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FirstClick = true;
|
|
}
|
|
}
|
|
}
|
|
if (DebugMode)
|
|
{
|
|
Debug.DrawRay(base.transform.position + RaycastOffset, Vector3.down.normalized * RaycastLength, Color.red, 0.01f, depthTest: false);
|
|
}
|
|
}
|
|
|
|
private void BresenhamLineAlgorithm(int x1, int x2, int y1, int y2)
|
|
{
|
|
int num = x2 - x1;
|
|
int num2 = y2 - y1;
|
|
int num3;
|
|
int num4;
|
|
if (num >= 0)
|
|
{
|
|
num3 = 1;
|
|
num4 = 1;
|
|
}
|
|
else
|
|
{
|
|
num3 = -1;
|
|
num4 = -1;
|
|
}
|
|
int num5;
|
|
int num6;
|
|
if (num2 >= 0)
|
|
{
|
|
num5 = 1;
|
|
num6 = 1;
|
|
}
|
|
else
|
|
{
|
|
num5 = -1;
|
|
num6 = -1;
|
|
}
|
|
num = Mathf.Abs(num);
|
|
num2 = Mathf.Abs(num2);
|
|
int num7;
|
|
int num8;
|
|
int num9;
|
|
int num10;
|
|
if (num >= num2)
|
|
{
|
|
num3 = 0;
|
|
num6 = 0;
|
|
num7 = num;
|
|
num8 = num / 2;
|
|
num9 = num2;
|
|
num10 = num;
|
|
}
|
|
else
|
|
{
|
|
num4 = 0;
|
|
num5 = 0;
|
|
num7 = num2;
|
|
num8 = num2 / 2;
|
|
num9 = num;
|
|
num10 = num2;
|
|
}
|
|
int num11 = x1;
|
|
int num12 = y1;
|
|
for (int i = 0; i <= num10; i++)
|
|
{
|
|
Hit.collider.gameObject.GetComponent<RealWaterInterface>().DisturbBufferAt(num11, num12, (int)(18000000f * InputForce), ambient: false);
|
|
num8 += num9;
|
|
if (num8 >= num7)
|
|
{
|
|
num8 -= num7;
|
|
num11 += num3;
|
|
num12 += num5;
|
|
}
|
|
num11 += num4;
|
|
num12 += num6;
|
|
}
|
|
}
|
|
}
|