summaryrefslogtreecommitdiff
path: root/GameCode/LineEffect.cs
diff options
context:
space:
mode:
Diffstat (limited to 'GameCode/LineEffect.cs')
-rw-r--r--GameCode/LineEffect.cs454
1 files changed, 454 insertions, 0 deletions
diff --git a/GameCode/LineEffect.cs b/GameCode/LineEffect.cs
new file mode 100644
index 0000000..ee2cd03
--- /dev/null
+++ b/GameCode/LineEffect.cs
@@ -0,0 +1,454 @@
+using System;
+using System.Collections;
+using Sirenix.OdinInspector;
+using UnityEngine;
+
+public class LineEffect : MonoBehaviour
+{
+ public enum LineType
+ {
+ Line,
+ Ring
+ }
+
+ public enum AnimType
+ {
+ Width,
+ Offset
+ }
+
+ public bool playOnAwake;
+
+ public bool loop;
+
+ public LineType lineType;
+
+ public int segments = 20;
+
+ public float globalTimeSpeed = 1f;
+
+ public bool raycastCollision;
+
+ [FoldoutGroup("Animation", 0)]
+ public AnimationCurve lineWidthOverTimeCurve = AnimationCurve.Linear(0f, 1f, 1f, 1f);
+
+ [Space(10f)]
+ [FoldoutGroup("Animation", 0)]
+ public bool useColorOverTime;
+
+ [FoldoutGroup("Animation", 0)]
+ [ShowIf("useColorOverTime", true)]
+ public Gradient colorOverTime;
+
+ [Space(10f)]
+ [FoldoutGroup("Animation", 0)]
+ [ShowIf("lineType", LineType.Ring, true)]
+ public float radius = 5f;
+
+ [FoldoutGroup("Animation", 0)]
+ [ShowIf("lineType", LineType.Ring, true)]
+ public AnimationCurve radiusOverTime = AnimationCurve.Linear(0f, 1f, 1f, 1f);
+
+ [Space(10f)]
+ [FoldoutGroup("Special", 0)]
+ public float inheritScaleFactor;
+
+ [Space(10f)]
+ public LineEffectInstance[] effects;
+
+ private LineRenderer line;
+
+ [HideInInspector]
+ public float counter;
+
+ private float startWidth;
+
+ [HideInInspector]
+ public float currentWidth;
+
+ [FoldoutGroup("Debug", 0)]
+ public bool debug;
+
+ [FoldoutGroup("Debug", 0)]
+ public Transform fromPos;
+
+ [FoldoutGroup("Debug", 0)]
+ public Transform toPos;
+
+ [FoldoutGroup("Debug", 0)]
+ public Transform bezierPos;
+
+ [HideInInspector]
+ public float offsetMultiplier = 1f;
+
+ [HideInInspector]
+ public float widthMultiplier = 1f;
+
+ private float scaleMultiplier = 1f;
+
+ private bool inited;
+
+ public bool isPlaying;
+
+ private Coroutine widthAnim;
+
+ private Coroutine offsetAnim;
+
+ private void Start()
+ {
+ globalTimeSpeed *= UnityEngine.Random.Range(0.95f, 1.05f);
+ }
+
+ private void OnEnable()
+ {
+ if (!inited)
+ {
+ Init();
+ }
+ if (playOnAwake && lineType == LineType.Ring)
+ {
+ Play(base.transform);
+ }
+ }
+
+ private void Init()
+ {
+ if (!inited)
+ {
+ line = GetComponent<LineRenderer>();
+ line.positionCount = segments;
+ line.useWorldSpace = true;
+ startWidth = line.widthMultiplier;
+ inited = true;
+ scaleMultiplier = 1f - inheritScaleFactor + base.transform.lossyScale.x * inheritScaleFactor;
+ }
+ }
+
+ private void Update()
+ {
+ if (!debug)
+ {
+ return;
+ }
+ if (lineType == LineType.Line && (bool)fromPos && (bool)toPos)
+ {
+ if ((bool)bezierPos)
+ {
+ DrawLine(fromPos.position, toPos.position, bezierPos.position);
+ }
+ else
+ {
+ DrawLine(fromPos.position, toPos.position);
+ }
+ }
+ if (lineType == LineType.Ring && (bool)fromPos)
+ {
+ DrawLine(fromPos.position, Vector3.zero);
+ }
+ }
+
+ public void StartDraw()
+ {
+ if (!base.gameObject.activeSelf)
+ {
+ base.gameObject.SetActive(value: true);
+ }
+ counter = 0f;
+ }
+
+ public void DrawLine(Vector3 start, Vector3 end)
+ {
+ DrawLine(start, end, Vector3.one * 100f);
+ }
+
+ public void DrawLine(Vector3 start, Vector3 end, Vector3 bezier)
+ {
+ Init();
+ Vector3 vector = Vector3.zero;
+ for (int i = 0; i < line.positionCount; i++)
+ {
+ float num = 0f;
+ for (int j = 0; j < effects.Length; j++)
+ {
+ if (!effects[j].active)
+ {
+ continue;
+ }
+ float num2 = 0f;
+ float num3 = (float)i / ((float)line.positionCount - 1f);
+ float time = num3;
+ float num4 = effects[j].mainCurveTiling;
+ if (effects[j].tilingPerMeter)
+ {
+ if (lineType == LineType.Line)
+ {
+ num4 *= (start - end).magnitude;
+ }
+ if (lineType == LineType.Ring)
+ {
+ num4 *= radius;
+ }
+ }
+ num3 *= num4;
+ if (effects[j].mainCurveScrollSpeed > 0f)
+ {
+ num3 += effects[j].mainCurveScrollSpeed * Time.unscaledTime;
+ }
+ if (effects[j].mainCurveScrollSpeed < 0f)
+ {
+ num3 += (0f - effects[j].mainCurveScrollSpeed) * (100000f - Time.unscaledTime);
+ }
+ num3 %= 1f;
+ num2 = effects[j].mainCurve.Evaluate(num3);
+ num2 *= effects[j].mainCurveMultiplier;
+ num2 *= effects[j].effectOverLineCurve.Evaluate(time);
+ num2 *= effects[j].effectOverTimeCurve.Evaluate(counter);
+ if (effects[j].curveType == LineEffectInstance.CurveType.Add)
+ {
+ num += num2;
+ }
+ else if (effects[j].curveType == LineEffectInstance.CurveType.Multiply)
+ {
+ num *= num2;
+ }
+ }
+ float t = (float)i / ((float)line.positionCount - 1f);
+ Vector3 vector2 = Vector3.zero;
+ Vector3 vector3 = Vector3.zero;
+ if (lineType == LineType.Ring)
+ {
+ float f = (float)Math.PI / 180f * ((float)i * 360f / (float)(segments - 1));
+ vector2 = start + new Vector3(Mathf.Sin(f) * (radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter)), Mathf.Cos(f) * (radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter)), 0f);
+ vector3 = ((!(vector != Vector3.zero)) ? Vector3.up : Vector3.Cross(Vector3.forward, vector2 - vector).normalized);
+ }
+ if (lineType == LineType.Line)
+ {
+ vector2 = Vector3.Lerp(start, end, t);
+ vector3 = Vector3.Cross(start - end, Vector3.forward).normalized;
+ if (bezier != Vector3.one * 100f)
+ {
+ vector2 = BezierCurve.QuadraticBezier(start, bezier, end, t);
+ }
+ }
+ vector = vector2;
+ line.SetPosition(i, vector2 + vector3 * num * offsetMultiplier);
+ }
+ if (raycastCollision)
+ {
+ RaycastPositions();
+ }
+ if (lineType == LineType.Ring)
+ {
+ SmoothSeam();
+ }
+ line.widthMultiplier = lineWidthOverTimeCurve.Evaluate(counter) * startWidth * scaleMultiplier * widthMultiplier;
+ currentWidth = line.widthMultiplier;
+ if (useColorOverTime)
+ {
+ line.startColor = colorOverTime.Evaluate(counter);
+ line.endColor = colorOverTime.Evaluate(counter);
+ }
+ counter += Time.unscaledDeltaTime * globalTimeSpeed;
+ if (counter > 1f)
+ {
+ if (debug || loop)
+ {
+ StartDraw();
+ }
+ else
+ {
+ base.gameObject.SetActive(value: false);
+ }
+ }
+ }
+
+ private void RaycastPositions()
+ {
+ for (int i = 0; i < line.positionCount; i++)
+ {
+ line.SetPosition(i, PhysicsFunctions.ObstructionPoint(base.transform.position, line.GetPosition(i)));
+ }
+ }
+
+ private void SmoothSeam()
+ {
+ float num = 0.1f;
+ Vector3 b = (line.GetPosition(0) + line.GetPosition(line.positionCount - 1)) * 0.5f;
+ for (int i = 0; i < line.positionCount; i++)
+ {
+ float num2 = (float)i / ((float)line.positionCount - 1f);
+ _ = Vector3.zero;
+ Vector3 zero = Vector3.zero;
+ Vector3 position = line.GetPosition(i);
+ float t;
+ if (num2 > 0.5f)
+ {
+ t = Mathf.Clamp((num2 - (1f - num)) / num, 0f, 1f);
+ }
+ else
+ {
+ t = Mathf.Clamp(num2 * (1f / num), 0f, 1f);
+ t = 1f - t;
+ }
+ zero = Vector3.Lerp(position, b, t) - position;
+ zero.x *= 0.5f;
+ line.SetPosition(i, position + zero);
+ }
+ line.SetPosition(1, new Vector3(line.GetPosition(1).x, b.y));
+ line.SetPosition(line.positionCount - 2, new Vector3(line.GetPosition(line.positionCount - 2).x, b.y));
+ }
+
+ public void Stop()
+ {
+ StopAllCoroutines();
+ if (!loop)
+ {
+ base.gameObject.SetActive(value: false);
+ }
+ }
+
+ public void Play()
+ {
+ Play(base.transform);
+ }
+
+ private void OnDisable()
+ {
+ Stop();
+ }
+
+ public void ResetMultipliers()
+ {
+ offsetMultiplier = 1f;
+ scaleMultiplier = 1f;
+ widthMultiplier = 1f;
+ }
+
+ public void Play(Transform fromTransform, Transform toTransform, float bezierOffset = 0f)
+ {
+ StartDraw();
+ StopAllCoroutines();
+ StartCoroutine(DoPlay(fromTransform, toTransform, bezierOffset));
+ }
+
+ private IEnumerator DoPlay(Transform fromTransform, Transform toTransform, float bezierOffset = 0f)
+ {
+ isPlaying = true;
+ Vector3 currentBez = Vector3.zero;
+ while (base.gameObject.activeSelf && (bool)fromTransform && (bool)toTransform)
+ {
+ if (bezierOffset != 0f)
+ {
+ float num = 1f;
+ if (toTransform.position.x < fromTransform.position.x)
+ {
+ num = -1f;
+ }
+ Vector3 vector = Vector3.Cross(Vector3.forward, toTransform.position - fromTransform.position).normalized * bezierOffset * num;
+ currentBez = ((!(currentBez == Vector3.zero)) ? Vector3.Lerp(currentBez, vector, TimeHandler.deltaTime * 5f) : vector);
+ Vector3 bezier = currentBez + (fromTransform.position + toTransform.position) * 0.5f;
+ DrawLine(fromTransform.position, toTransform.position, bezier);
+ }
+ else
+ {
+ DrawLine(fromTransform.position, toTransform.position);
+ }
+ yield return null;
+ }
+ isPlaying = false;
+ }
+
+ public void Play(Transform fromTransform, Vector3 toPosition, float bezierOffset = 0f)
+ {
+ StartDraw();
+ StopAllCoroutines();
+ StartCoroutine(DoPlay(fromTransform, toPosition, bezierOffset));
+ }
+
+ private IEnumerator DoPlay(Transform fromTransform, Vector3 toPosition, float bezierOffset = 0f)
+ {
+ Vector3 currentBezOffset = Vector3.zero;
+ while (base.gameObject.activeSelf && (bool)fromTransform)
+ {
+ if (bezierOffset != 0f)
+ {
+ float num = 1f;
+ if (toPosition.x < fromTransform.position.x)
+ {
+ num = -1f;
+ }
+ Vector3 vector = Vector3.Cross(Vector3.forward, toPosition - fromTransform.position).normalized * bezierOffset * num;
+ currentBezOffset = ((!(currentBezOffset == Vector3.zero)) ? Vector3.Lerp(currentBezOffset, vector, TimeHandler.deltaTime * 2f) : vector);
+ _ = currentBezOffset + (fromTransform.position + toPosition) * 0.5f;
+ Vector3 bezier = (fromTransform.position + toPosition) * 0.5f;
+ DrawLine(fromTransform.position, toPosition, bezier);
+ }
+ else
+ {
+ DrawLine(fromTransform.position, toPosition);
+ }
+ yield return null;
+ }
+ }
+
+ public void Play(Transform fromTransform)
+ {
+ StartDraw();
+ StopAllCoroutines();
+ StartCoroutine(DoPlay(fromTransform));
+ }
+
+ private IEnumerator DoPlay(Transform fromTransform)
+ {
+ while (base.gameObject.activeSelf && (bool)fromTransform)
+ {
+ DrawLine(fromTransform.position, Vector3.zero);
+ yield return null;
+ }
+ }
+
+ public void PlayAnim(AnimType animType, AnimationCurve curve, float speed = 1f)
+ {
+ if (animType == AnimType.Offset && offsetAnim != null)
+ {
+ StopCoroutine(offsetAnim);
+ }
+ if (animType == AnimType.Width && widthAnim != null)
+ {
+ StopCoroutine(widthAnim);
+ }
+ Coroutine coroutine = StartCoroutine(DoPlayAnim(animType, curve, speed));
+ if (animType == AnimType.Offset)
+ {
+ offsetAnim = coroutine;
+ }
+ if (animType == AnimType.Width)
+ {
+ widthAnim = coroutine;
+ }
+ }
+
+ private IEnumerator DoPlayAnim(AnimType animType, AnimationCurve curve, float speed = 1f)
+ {
+ float c = 0f;
+ float t = curve.keys[curve.keys.Length - 1].time;
+ while (c < t)
+ {
+ if (animType == AnimType.Offset)
+ {
+ offsetMultiplier = curve.Evaluate(c);
+ }
+ if (animType == AnimType.Width)
+ {
+ widthMultiplier = curve.Evaluate(c);
+ }
+ c += TimeHandler.deltaTime * speed;
+ yield return null;
+ }
+ }
+
+ internal float GetRadius()
+ {
+ return radius * base.transform.root.localScale.x * radiusOverTime.Evaluate(counter);
+ }
+}