432 lines
11 KiB
C#
432 lines
11 KiB
C#
using UnityEngine;
|
|
|
|
public class RealWaterCollider : MonoBehaviour
|
|
{
|
|
public enum Objecttype
|
|
{
|
|
RigidBody = 0,
|
|
CharacterController = 1
|
|
}
|
|
|
|
private float xCoord;
|
|
|
|
private float YCoord;
|
|
|
|
[Tooltip("If true this input will be used for collision culling and as the center of normal map mode simulations. You should only have one per scene!")]
|
|
public bool mainInput;
|
|
|
|
[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;
|
|
|
|
[Tooltip("Ensures input position of RealWaterNormal map instances is updated frequently enough to prevent errors with fade algorithm at low speeds (<~10).")]
|
|
public bool lowSpeedMode;
|
|
|
|
private float zPositionCurrent;
|
|
|
|
private float xPositionCurrent;
|
|
|
|
private float zPositionPrevious;
|
|
|
|
private float xPositionPrevious;
|
|
|
|
private bool checkWaterCollision = true;
|
|
|
|
private bool crouching;
|
|
|
|
private RWInput rwInput = new RWInput();
|
|
|
|
private BresenhamLineDrawer lineDrawer = new BresenhamLineDrawer();
|
|
|
|
private bool firstRun = true;
|
|
|
|
private float collisionCheckFrequency = 60f;
|
|
|
|
private bool isCharController;
|
|
|
|
private bool isRigidbody;
|
|
|
|
private CharacterController controller;
|
|
|
|
private RaycastHit hit;
|
|
|
|
private int baseForce = 18000000;
|
|
|
|
private bool visible = true;
|
|
|
|
private RealWaterInterface previousPlane;
|
|
|
|
public static bool reseting;
|
|
|
|
private void Start()
|
|
{
|
|
switch (ObjectType)
|
|
{
|
|
case Objecttype.CharacterController:
|
|
isCharController = true;
|
|
controller = GetComponent<CharacterController>();
|
|
break;
|
|
case Objecttype.RigidBody:
|
|
isRigidbody = true;
|
|
break;
|
|
}
|
|
if (DebugMode)
|
|
{
|
|
VelocityLimit = -1f;
|
|
}
|
|
else
|
|
{
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
}
|
|
if (!FirstPersonMode && !DebugMode)
|
|
{
|
|
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
|
|
}
|
|
if (mainInput && lowSpeedMode)
|
|
{
|
|
InvokeRepeating("LowSpeedInputPositionSet", 0.001f, 1f / 30f);
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (reseting)
|
|
{
|
|
Reset();
|
|
}
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
}
|
|
|
|
private void LowSpeedInputPositionSet()
|
|
{
|
|
if (Physics.Raycast(base.transform.position + RaycastOffset, Vector3.down, out var hitInfo, RaycastLength) && hitInfo.collider.gameObject.name == "RealWater Plane")
|
|
{
|
|
xCoord = hitInfo.textureCoord.x;
|
|
YCoord = hitInfo.textureCoord.y;
|
|
int rows = hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().GetRows();
|
|
int cols = hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().GetCols();
|
|
int num = (int)(YCoord * (float)rows);
|
|
int num2 = (int)(xCoord * (float)cols);
|
|
if (!hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().IsFullPlaneSim())
|
|
{
|
|
hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().SetInputPos(new Vector2(num, num2));
|
|
}
|
|
}
|
|
}
|
|
|
|
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 (isRigidbody)
|
|
{
|
|
if (Mathf.Round(GetComponent<Rigidbody>().velocity.y) == 0f)
|
|
{
|
|
if (zPositionCurrent == zPositionPrevious && xPositionCurrent == xPositionPrevious)
|
|
{
|
|
checkWaterCollision = false;
|
|
}
|
|
else if (!crouching)
|
|
{
|
|
checkWaterCollision = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
checkWaterCollision = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!isCharController)
|
|
{
|
|
return;
|
|
}
|
|
if (Mathf.Round(controller.velocity.y) == 0f)
|
|
{
|
|
if (zPositionCurrent == zPositionPrevious && xPositionCurrent == xPositionPrevious)
|
|
{
|
|
checkWaterCollision = false;
|
|
}
|
|
else if (!crouching)
|
|
{
|
|
checkWaterCollision = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
checkWaterCollision = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void VisibilityCheck()
|
|
{
|
|
if (!GetComponent<Renderer>().isVisible && !DebugMode)
|
|
{
|
|
CancelInvoke("CheckForCollisions");
|
|
CancelInvoke("PositionCheck1");
|
|
visible = false;
|
|
}
|
|
else if (!visible && GetComponent<Renderer>().isVisible)
|
|
{
|
|
InvokeRepeating("CheckForCollisions", 0.005f, 1f / collisionCheckFrequency);
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
rwInput.SetFirstInput(val: true);
|
|
visible = true;
|
|
}
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
CancelInvoke();
|
|
RealWaterSpeedManager realWaterSpeedManager = Object.FindObjectOfType(typeof(RealWaterSpeedManager)) as RealWaterSpeedManager;
|
|
if (realWaterSpeedManager != null)
|
|
{
|
|
realWaterSpeedManager.FindColliders();
|
|
}
|
|
rwInput.SetFirstInput(val: true);
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
if (!firstRun)
|
|
{
|
|
RealWaterSpeedManager realWaterSpeedManager = Object.FindObjectOfType(typeof(RealWaterSpeedManager)) as RealWaterSpeedManager;
|
|
if (realWaterSpeedManager != null)
|
|
{
|
|
realWaterSpeedManager.FindColliders();
|
|
}
|
|
if (!FirstPersonMode && !DebugMode)
|
|
{
|
|
InvokeRepeating("VisibilityCheck", 0.001f, 0.2f);
|
|
}
|
|
if (!crouching)
|
|
{
|
|
checkWaterCollision = true;
|
|
}
|
|
InvokeRepeating("PositionCheck1", 0.001f, 1f / 30f);
|
|
}
|
|
else
|
|
{
|
|
firstRun = false;
|
|
}
|
|
}
|
|
|
|
private void CheckForCollisions()
|
|
{
|
|
if (!checkWaterCollision)
|
|
{
|
|
return;
|
|
}
|
|
if (Physics.Raycast(base.transform.position + RaycastOffset, Vector3.down, out var hitInfo, 100f) && hitInfo.collider.gameObject.name == "RealWater Plane")
|
|
{
|
|
xCoord = hitInfo.textureCoord.x;
|
|
YCoord = hitInfo.textureCoord.y;
|
|
int rows = hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().GetRows();
|
|
int cols = hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().GetCols();
|
|
int num = (int)(YCoord * (float)rows);
|
|
int num2 = (int)(xCoord * (float)cols);
|
|
if (!hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().IsFullPlaneSim())
|
|
{
|
|
hitInfo.collider.gameObject.GetComponent<RealWaterInterface>().SetInputPos(new Vector2(num, num2));
|
|
}
|
|
}
|
|
if (DebugMode)
|
|
{
|
|
Debug.DrawRay(base.transform.position + RaycastOffset, Vector3.down.normalized * RaycastLength, Color.red, 0.01f, depthTest: false);
|
|
}
|
|
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 (mainInput && previousPlane != null)
|
|
{
|
|
((MonoBehaviour)previousPlane).CancelInvoke("Pause");
|
|
if (previousPlane.GetPaused() && hit.collider.gameObject.GetComponent<RealWaterInterface>().GetCollisionCulling() && !hit.collider.gameObject.GetComponent<RealWaterInterface>().GetAmbientMode())
|
|
{
|
|
hit.collider.gameObject.GetComponent<RealWaterInterface>().Play();
|
|
}
|
|
}
|
|
if (isRigidbody)
|
|
{
|
|
if (GetComponent<Rigidbody>().velocity.magnitude > VelocityLimit)
|
|
{
|
|
ProcessCollision();
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
}
|
|
}
|
|
else if (controller.velocity.magnitude > VelocityLimit)
|
|
{
|
|
ProcessCollision();
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
}
|
|
if (previousPlane == null)
|
|
{
|
|
previousPlane = hit.collider.gameObject.GetComponent<RealWaterInterface>();
|
|
}
|
|
else if (previousPlane != hit.collider.gameObject.GetComponent<RealWaterInterface>() && mainInput && previousPlane.GetCollisionCulling() && !previousPlane.GetAmbientMode() && mainInput)
|
|
{
|
|
((MonoBehaviour)previousPlane).Invoke("Pause", previousPlane.GetInterPlanePauseDelay());
|
|
previousPlane = hit.collider.gameObject.GetComponent<RealWaterInterface>();
|
|
}
|
|
else
|
|
{
|
|
previousPlane = hit.collider.gameObject.GetComponent<RealWaterInterface>();
|
|
}
|
|
}
|
|
else if (previousPlane != null)
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
if (!previousPlane.GetPaused() && mainInput && !previousPlane.GetAmbientMode() && previousPlane.GetCollisionCulling() && mainInput)
|
|
{
|
|
((MonoBehaviour)previousPlane).Invoke("Pause", previousPlane.GetExitPauseDelay());
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
if (previousPlane != null && !previousPlane.GetPaused() && mainInput && !previousPlane.GetAmbientMode() && previousPlane.GetCollisionCulling() && mainInput)
|
|
{
|
|
((MonoBehaviour)previousPlane).Invoke("Pause", previousPlane.GetExitPauseDelay());
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ProcessCollision()
|
|
{
|
|
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();
|
|
int num = (int)(YCoord * (float)rows);
|
|
int num2 = (int)(xCoord * (float)cols);
|
|
bool visibility = hit.collider.gameObject.GetComponent<RealWaterInterface>().GetVisibility();
|
|
bool paused = hit.collider.gameObject.GetComponent<RealWaterInterface>().GetPaused();
|
|
if (mainInput && !hit.collider.gameObject.GetComponent<RealWaterInterface>().IsFullPlaneSim())
|
|
{
|
|
hit.collider.gameObject.GetComponent<RealWaterInterface>().SetInputPos(new Vector2(num, num2));
|
|
}
|
|
if (!paused && visibility && num2 > bR + 1 && num2 < cols - bR + 1 && num < rows - (bR + 2) && num > bR + 2)
|
|
{
|
|
if (ExtrapolateInput)
|
|
{
|
|
if (!rwInput.GetFirstInput())
|
|
{
|
|
if (rwInput.GetFirstPoint())
|
|
{
|
|
rwInput.SetX1(num);
|
|
rwInput.SetY1(num2);
|
|
rwInput.SetPlane1(hit.collider.GetInstanceID());
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetX2(num);
|
|
rwInput.SetY2(num2);
|
|
rwInput.SetPlane2(hit.collider.GetInstanceID());
|
|
}
|
|
if (rwInput.GetPlane1() == rwInput.GetPlane2())
|
|
{
|
|
lineDrawer.DrawLine(rwInput.GetX1(), rwInput.GetX2(), rwInput.GetY1(), rwInput.GetY2(), hit, InputForce);
|
|
}
|
|
rwInput.SetFirstPoint(!rwInput.GetFirstPoint());
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetX1(num);
|
|
rwInput.SetY1(num2);
|
|
rwInput.SetX2(num);
|
|
rwInput.SetY2(num2);
|
|
rwInput.SetFirstInput(val: false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hit.collider.gameObject.GetComponent<RealWaterInterface>().DisturbBufferAt(num, num2, (int)(18000000f * InputForce), ambient: false);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rwInput.SetFirstInput(val: true);
|
|
}
|
|
}
|
|
|
|
public bool GetCrouching()
|
|
{
|
|
return crouching;
|
|
}
|
|
|
|
public void SetCrouching(bool val)
|
|
{
|
|
crouching = val;
|
|
}
|
|
|
|
public bool GetCheckCollisions()
|
|
{
|
|
return checkWaterCollision;
|
|
}
|
|
|
|
public void SetCheckCollisions(bool val)
|
|
{
|
|
checkWaterCollision = val;
|
|
}
|
|
|
|
public float GetCollisionFrequency()
|
|
{
|
|
return collisionCheckFrequency;
|
|
}
|
|
|
|
public void SetCollisionFrequency(float val)
|
|
{
|
|
collisionCheckFrequency = val;
|
|
}
|
|
|
|
public bool GetVisibility()
|
|
{
|
|
return visible;
|
|
}
|
|
}
|