You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.4 KiB

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class WaterController : MonoBehaviour {
  5. public AnimationCurve RipplePower;
  6. private float waveOffset = 0;
  7. public float waveScale = 1;
  8. public float waterWidth = 1;
  9. public float waveSpeed = 1;
  10. public float maxWaveHeight = 2;
  11. private readonly float scaleConstant = 75f;
  12. public GameObject rippleEffect;
  13. #region Unity Functions
  14. // Use this for initialization
  15. void Start() {
  16. }
  17. // Update is called once per frame
  18. void Update() {
  19. waveOffset += 0.1f *waveSpeed * Time.deltaTime;
  20. }
  21. #endregion Unity Fucntions
  22. #region Interaction Functions
  23. /// <summary>
  24. /// Pushes any objects in water away from this point
  25. /// </summary>
  26. /// <param name="point"> point where water is createds</param>
  27. /// <param name="radius"> radius of effected object</param>
  28. /// <param name="power"> power with chich the objects are pushed</param>
  29. public void CreateWave(Vector3 point, float radius, float power) {
  30. NotificationServer.notify("play sfx", "createWave_3:0.2");
  31. //find all colliders within the wave distance
  32. point.y = transform.position.y;
  33. Vector3 pos = point;
  34. pos.y += 1;
  35. Quaternion rot = Quaternion.Euler(-90, 0, 0);
  36. if (rippleEffect != null) {
  37. GameObject ripple = Instantiate(rippleEffect, pos, rot);
  38. Vector3 scale = Vector3.one * radius / scaleConstant;
  39. ripple.transform.localScale = scale;
  40. Destroy(ripple, 4);
  41. }
  42. Collider[] colliders = Physics.OverlapSphere(point, radius);
  43. foreach (Collider hit in colliders) {
  44. BuoyantObject hitScript = hit.gameObject.GetComponent<BuoyantObject>();
  45. if (hitScript != null) {
  46. Debug.DrawLine(point, hit.transform.position, Color.blue, 1);
  47. StartCoroutine(hitScript.pushObject(point, power, 2));
  48. }
  49. //StartCoroutine(waveController(point, radius, power, 2));
  50. }
  51. }
  52. #endregion Interaction Functions
  53. #region Helper Functions
  54. private IEnumerator waveController (Vector3 point, float radius, float power, float rippleTime) {
  55. float elapsedTime = 0.0f;
  56. while (elapsedTime < rippleTime) {
  57. float curRippleForce = RipplePower.Evaluate(elapsedTime / rippleTime);
  58. Collider[] colliders = Physics.OverlapSphere(point, radius);
  59. foreach (Collider hit in colliders) {
  60. Rigidbody rb = hit.GetComponent<Rigidbody>();
  61. Debug.DrawLine(point, hit.transform.position, Color.blue, 1);
  62. if (rb != null) {
  63. Debug.DrawLine(point, hit.transform.position, Color.blue, 1);
  64. Vector3 flatPoint = new Vector3(point.x, hit.transform.position.y, point.z);
  65. rb.AddExplosionForce(power * curRippleForce, point, radius, 0.0f);
  66. }
  67. }
  68. yield return new WaitForEndOfFrame();
  69. elapsedTime += Time.deltaTime;
  70. }
  71. }
  72. #endregion Helper Functions
  73. #region Collision Functions
  74. void OnTriggerEnter(Collider other) {
  75. //calls appropriate function if the object should interact with the water on enter
  76. WaterObject waterInteraction = other.gameObject.GetComponent<WaterObject>();
  77. if (waterInteraction != null) {
  78. waterInteraction.OnWaterEnter(this);
  79. }
  80. }
  81. void OnTriggerStay(Collider other) {
  82. //calls appropriate function if the object should interact with the water on stay
  83. WaterObject waterInteraction = other.gameObject.GetComponent<WaterObject>();
  84. if (waterInteraction != null) {
  85. Vector2 waveCoords = new Vector2(other.transform.position.x, other.transform.position.z);
  86. waveCoords = waveCoords / waterWidth * waveScale;
  87. float waveHeight = Mathf.PerlinNoise(waveCoords.x, waveCoords.y + waveOffset);
  88. waterInteraction.OnWaterStay(this,waveHeight * maxWaveHeight);
  89. }
  90. }
  91. void OnTriggerExit(Collider other) {
  92. //calls appropriate function if the object should interact with the water on exit
  93. WaterObject waterInteraction = other.gameObject.GetComponent<WaterObject>();
  94. if (waterInteraction != null) {
  95. waterInteraction.OnWaterExit(this);
  96. }
  97. }
  98. #endregion Collision Functions
  99. }