summaryrefslogtreecommitdiff
path: root/Assets/Art/Vfx/GrabSquaresEffect/Scripts/MoveableLineRenderer.cs
blob: dc2d723d40dc851c9adf3134d9f0ffd898da5726 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
using System.Linq;
using UnityEngine;

namespace Assets.MoveableLineRenderer.Scripts
{
    internal sealed class MoveableLineRenderer : MonoBehaviour
    {
        public GameObject LineRendererPrefab;
        public float MinVertexDistance = 1f;
        public float LifeTime = 0.3f;
        public float Scale = 1.0f;
        public float Speed = 1f;
        public float Height = 1f;
        public float Gravity;

        private LineRenderer _lineRenderer;
        private Point[] _points;
        private int _pointsCount;

        private void Start()
        {
            _lineRenderer = Instantiate(LineRendererPrefab).GetComponent<LineRenderer>();
            _lineRenderer.enabled = true;
            _lineRenderer.transform.parent = transform;

            _points = new Point[100];
        }

        private void Update()
        {
            RemoveOutdatedPoints();

            if (_pointsCount == 0)
            {
                _points[_pointsCount++] = new Point(transform.position);
                _points[_pointsCount++] = new Point(transform.position);
            }

            bool needAdd = false;

            var sqrDistance = (_points[1].Position - transform.position).sqrMagnitude;
            if (sqrDistance > MinVertexDistance * MinVertexDistance)
            {
                if (sqrDistance > MinVertexDistance * MinVertexDistance)
                    needAdd = true;
            }

            if (needAdd)
            {
                if (_pointsCount == _points.Length)
                    System.Array.Resize(ref _points, _points.Length + 50);

                InsertPoint();
            }

            ApplyTurbulence();

            _lineRenderer.positionCount = _pointsCount;

            //todo
            _lineRenderer.SetPositions(_points.Where(t => t != null).Select(t => t.Position).ToArray());
        }

        private void InsertPoint()
        {
            for (int i = _pointsCount; i > 0; i--)
                _points[i] = _points[i - 1];

            _points[0] = new Point(transform.position);

            _pointsCount++;
        }

        private void RemoveOutdatedPoints()
        {
            if (_pointsCount == 0)
                return;

            for (int i = _pointsCount - 1; i >= 0; i--)
            {
                var point = _points[i];
                if (point == null || point.TimeAlive >= LifeTime)
                {
                    _points[i] = null;
                    _pointsCount--;
                }
            }
        }

        private void ApplyTurbulence()
        {
            for (int i = _pointsCount - 1; i >= 0; i--)
            {
                if (_points[i] == null)
                    continue;

                var sTime = Time.timeSinceLevelLoad * Speed;

                var pointPosition = _points[i].Position;

                float xCoord = pointPosition.x * Scale + sTime;
                float yCoord = pointPosition.y * Scale + sTime;
                float zCoord = pointPosition.z * Scale + sTime;

                _points[i].Position.x += (Mathf.PerlinNoise(yCoord, zCoord) - 0.5f) * Height;
                _points[i].Position.y += (Mathf.PerlinNoise(xCoord, zCoord) - 0.5f) * Height - Gravity;
                _points[i].Position.z += (Mathf.PerlinNoise(xCoord, yCoord) - 0.5f) * Height;
            }
        }
    }
}