diff options
author | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2023-10-27 11:05:14 +0800 |
commit | 766cdff5ffa72b65d7f106658d1603f47739b2ba (patch) | |
tree | 34d7799a94dfa9be182825577583c0fa6dc935f7 /GameCode/LineEffect.cs |
+ init
Diffstat (limited to 'GameCode/LineEffect.cs')
-rw-r--r-- | GameCode/LineEffect.cs | 454 |
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); + } +} |