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(); 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().isVisible && !DebugMode) { CancelInvoke("PositionCheck1"); CancelInvoke("CheckForCollisions"); Visible = false; } else if (!Visible && ParentCollider.GetComponent().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().velocity.magnitude > VelocityLimit) { XCoord = Hit.textureCoord.x; YCoord = Hit.textureCoord.y; int rows = Hit.collider.gameObject.GetComponent().GetRows(); int cols = Hit.collider.gameObject.GetComponent().GetCols(); int bR = Hit.collider.gameObject.GetComponent().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().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().GetRows(); int cols2 = Hit.collider.gameObject.GetComponent().GetCols(); int bR2 = Hit.collider.gameObject.GetComponent().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().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().DisturbBufferAt(num11, num12, (int)(18000000f * InputForce), ambient: false); num8 += num9; if (num8 >= num7) { num8 -= num7; num11 += num3; num12 += num5; } num11 += num4; num12 += num6; } } }