using System.Collections; using System.Collections.Generic; using UnityEngine; namespace BoatAttack.Boat { /// /// Used to generate two wakes (linerenderers) for the boats /// public class WakeGenerator : MonoBehaviour { public List _wakes = new List(); // Wakes to create private List _lrs = new List(); // line renderers public GameObject _wakePrefab; // the wake prefab, preset linerenderer public float _genDistance = 0.5f; // distance to make new segments public float _maxAge = 5f; // how long the wake lasts for void OnEnable() { // Initial setup for wakes foreach (Wake w in _wakes) { for (int i = 0; i < 2; i++) { WakeLine wl = new WakeLine(); GameObject go = GameObject.Instantiate(_wakePrefab, Vector3.zero, Quaternion.Euler(90f, 0, 0)); _lrs.Add(go); LineRenderer LR = go.GetComponent(); wl.points = new List(); wl._lineRenderer = LR; w.lines.Add(wl); go.hideFlags = HideFlags.HideAndDontSave; } } } void OnDisable() { for (int i = _lrs.Count - 1; i >= 0; i--) { DestroyImmediate(_lrs[i]); // kill wake objects } _lrs.Clear(); } void Update() { Vector3 origin; //For each wake pair for (int w = 0; w < _wakes.Count; w++) { Wake _wake = _wakes[w]; int s = 0; for (int x = -1; x <= 1; x += 2) { origin = _wake.origin; origin.x *= x; origin = transform.TransformPoint(origin); origin.y = 0;//flatten origin in world //////////////////////////// create points, if needed /////////////////////////////// if (_wake.lines[s].points.Count == 0) { _wake.lines[s].points.Insert(0, CreateWakePoint(origin, x)); } else if (Vector3.Distance(_wake.lines[s].points[0].pos, origin) > _genDistance) { _wake.lines[s].points.Insert(0, CreateWakePoint(origin, x)); } ///////////////////////////// kill points, if needed //////////////////////////////// for (int i = _wake.lines[s].points.Count - 1; i >= 0; i--) { if (_wake.lines[s].points[i].age > _maxAge) { _wake.lines[s].points.RemoveAt(i); } else { _wake.lines[s].points[i].age += Time.deltaTime; // increment age _wake.lines[s].points[i].pos += _wake.lines[s].points[i].dir * 3 * Time.deltaTime; // move points by dir } } ///////////////////// Create the line renderer points /////////////////////////////// Vector3[] points = new Vector3[_wake.lines[s].points.Count + 1]; points[0] = origin; for (var p = 1; p < points.Length - 1; p++) points[p] = _wake.lines[s].points[p - 1].pos; _wake.lines[s]._lineRenderer.positionCount = _wake.lines[s].points.Count; _wake.lines[s]._lineRenderer.SetPositions(points); s++; } } } /// /// Creates a WakePoint and sets the direction /// /// Where to make the wake point in world coords /// Side of the wake this is on /// WakePoint CreateWakePoint(Vector3 pos, float sign) { WakePoint wp = new WakePoint(pos); wp.dir = transform.right * sign; // the point gets the direction of the side of the boat, thhis is then used to move the wake as it ages wp.dir.y = 0; return wp; } // Draw helper Gizmos void OnDrawGizmosSelected() { Gizmos.color = Color.green; foreach (Wake w in _wakes) { Gizmos.DrawSphere(transform.TransformPoint(w.origin.x, w.origin.y, w.origin.z), 0.1f); Gizmos.DrawSphere(transform.TransformPoint(-w.origin.x, w.origin.y, w.origin.z), 0.1f); } foreach (Wake w in _wakes) { foreach (WakeLine wl in w.lines) { int side = 0; foreach (WakePoint wp in wl.points) { Gizmos.DrawSphere(wp.pos, (_maxAge - wp.age) * 0.05f); } side++; } } } /// /// Wake is a pair of line renderers stored in WakeLines /// [System.Serializable] public class Wake { public Vector3 origin; // Wehre the wake originates from in local coords public List lines = new List(); // Wake Lines } /// /// WakeLine is a single side of a wake, it contains a line renderer and list of wakepoints /// [System.Serializable] public class WakeLine { public LineRenderer _lineRenderer; // the linerenderer public List points = new List(); // list of points } /// /// A single wake point /// [System.Serializable] public class WakePoint { public Vector3 pos; // The current position public Vector3 dir; // the directions of movement public float age; // the age of the point public WakePoint(Vector3 p) { pos = p; age = 0f; } } } }