using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaterController : MonoBehaviour { public AnimationCurve RipplePower; private float waveOffset = 0; public float waveScale = 1; public float waterWidth = 1; public float waveSpeed = 1; public float maxWaveHeight = 2; private readonly float scaleConstant = 75f; public GameObject rippleEffect; #region Unity Functions // Use this for initialization void Start() { } // Update is called once per frame void Update() { waveOffset += 0.1f *waveSpeed * Time.deltaTime; } #endregion Unity Fucntions #region Interaction Functions /// /// Pushes any objects in water away from this point /// /// point where water is createds /// radius of effected object /// power with chich the objects are pushed public void CreateWave(Vector3 point, float radius, float power) { //find all colliders within the wave distance point.y = transform.position.y; Vector3 pos = point; pos.y += 1; Quaternion rot = Quaternion.Euler(-90, 0, 0); if (rippleEffect != null) { GameObject ripple = Instantiate(rippleEffect, pos, rot); Vector3 scale = Vector3.one * radius / scaleConstant; ripple.transform.localScale = scale; Destroy(ripple, 4); } Collider[] colliders = Physics.OverlapSphere(point, radius); foreach (Collider hit in colliders) { BuoyantObject hitScript = hit.gameObject.GetComponent(); if (hitScript != null) { Debug.DrawLine(point, hit.transform.position, Color.blue, 1); StartCoroutine(hitScript.pushObject(point, power, 2)); } //StartCoroutine(waveController(point, radius, power, 2)); } } #endregion Interaction Functions #region Helper Functions private IEnumerator waveController (Vector3 point, float radius, float power, float rippleTime) { float elapsedTime = 0.0f; while (elapsedTime < rippleTime) { float curRippleForce = RipplePower.Evaluate(elapsedTime / rippleTime); Collider[] colliders = Physics.OverlapSphere(point, radius); foreach (Collider hit in colliders) { Rigidbody rb = hit.GetComponent(); Debug.DrawLine(point, hit.transform.position, Color.blue, 1); if (rb != null) { Debug.DrawLine(point, hit.transform.position, Color.blue, 1); Vector3 flatPoint = new Vector3(point.x, hit.transform.position.y, point.z); rb.AddExplosionForce(power * curRippleForce, point, radius, 0.0f); } } yield return new WaitForEndOfFrame(); elapsedTime += Time.deltaTime; } } #endregion Helper Functions #region Collision Functions void OnTriggerEnter(Collider other) { //calls appropriate function if the object should interact with the water on enter WaterObject waterInteraction = other.gameObject.GetComponent(); if (waterInteraction != null) { waterInteraction.OnWaterEnter(this); } } void OnTriggerStay(Collider other) { //calls appropriate function if the object should interact with the water on stay WaterObject waterInteraction = other.gameObject.GetComponent(); if (waterInteraction != null) { Vector2 waveCoords = new Vector2(other.transform.position.x, other.transform.position.z); waveCoords = waveCoords / waterWidth * waveScale; float waveHeight = Mathf.PerlinNoise(waveCoords.x, waveCoords.y + waveOffset); waterInteraction.OnWaterStay(this,waveHeight * maxWaveHeight); } } void OnTriggerExit(Collider other) { //calls appropriate function if the object should interact with the water on exit WaterObject waterInteraction = other.gameObject.GetComponent(); if (waterInteraction != null) { waterInteraction.OnWaterExit(this); } } #endregion Collision Functions }