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.3 KiB

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
/// <summary>
/// Pushes any objects in water away from this point
/// </summary>
/// <param name="point"> point where water is createds</param>
/// <param name="radius"> radius of effected object</param>
/// <param name="power"> power with chich the objects are pushed</param>
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<BuoyantObject>();
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<Rigidbody>();
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<WaterObject>();
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<WaterObject>();
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<WaterObject>();
if (waterInteraction != null) {
waterInteraction.OnWaterExit(this);
}
}
#endregion Collision Functions
}