Unity LineRenderer 实现闪电效果

Unity LineRenderer 实现闪电效果一 前言 起初在制作塔防小游戏 想要实现红警中磁暴攻击效果 就找到这样一个制作思路就想自己能不能实现一下 独游工具箱 使用 Unity 中 LineRenderer 组件制作闪电特效 哔哩哔哩 bilibili 效果视频 unity 使用 Line Renderer 实现闪电效果 哔哩哔哩 bilibili 效果图

大家好,我是讯享网,很高兴认识大家。

一、前言

起初在制作塔防小游戏,想要实现红警中磁暴攻击效果,就找到这样一个制作思路就想自己能不能实现一下。

【独游工具箱】使用Unity中LineRenderer组件制作闪电特效_哔哩哔哩_bilibili

 效果视频:

unity 使用Line Renderer实现闪电效果_哔哩哔哩_bilibili

效果图:


讯享网

 二、步骤

我的实现比较简单粗暴,从图片可以看出使用了多条线拼合在一起做到的闪电。

所以第一步就多建几个空物体,加上LineRenderer组件。这里cube我是用来充当碰撞体的。

 然后,每个空物体的LineRenderer组件中的position给他多加几个操控点,我加了22个,去掉头尾正好20个嘛。

然后给每条线挂在我们的脚本,让脚本控制它当中20个点的位移,模拟闪电不可预测的曲折的路径。怎么实现都可以,我这里参考了第一个视频链接里的方法

 1、首先让它电弧抖动。我直接让每条线所有的控制点去采样一条二次函数。

到这里算是代码的第一部分实现电弧抖动的部分,写成函数就是这样。不过这里是得到二次函数的值,而我们要将控制点慢慢地变换到最后,所以再拿到这个值后取插值。详见完整代码。

float Arcing(float param) { //就是一个二次函数写成了代码 return _ArcingPowParam1 * Mathf.Pow((param - (float)posList.Count / 2 + _CenterOffset) * _ArcingPowParam1,2) + _Adjust; }

讯享网

 2、然后就是让它的抖动有点变化,就是乘上一个Sin的曲线函数,通过缩放和偏移调整到想要的效果。

代码:

讯享网float Sine(float param) { return Mathf.Sin((float)param / posList.Count * 2 * 3.14f * _SineScaleX) * _SineScaleY; }

3、然后添加一点抖动。

抖动就是加减随机值。

Vector3 Wiggle(int listIndex) { Vector3 v = new Vector3(); if (X) v.x = Random.Range(0, 10) * _RandomSize; if (Y) v.y = Random.Range(0, 10) * _RandomSize; if (Z) v.z = Random.Range(0, 10) * _RandomSize; return v; }

4、给其他四条线同样挂载脚本,参数微调整体就效果就出来了。

挂载的脚本UI如下:

 

 三、完整代码

讯享网using System.Collections; using System.Collections.Generic; using UnityEngine; public class Thunder : MonoBehaviour { public int PosSize; public bool useArcing; public bool useSine; public bool useWiggle; public bool X, Y, Z; [Range(-1,1)] public float _ArcingPowParam1; [Range(0,5)] public float _SineScaleX; public float _SineScaleY; public float _CenterOffset; public float _Adjust; public float _RandomSize; public float _Speed; LineRenderer lineRenderer; List<Vector3> posList = new List<Vector3>(); [System.NonSerialized] public Vector3 startPos; [System.NonSerialized] public Vector3 endPos; float fps; float sineRandom; void Start() { lineRenderer = GetComponent<LineRenderer>(); startPos = lineRenderer.GetPosition(0); endPos = lineRenderer.GetPosition(1); LerpPos(); } void Update() { fps += Time.deltaTime*_Speed; if (fps >= 1) { sineRandom = (float)Random.Range(0, posList.Count * 10) / 10; fps = 0; } List<Vector3> list = new List<Vector3>(); for (int i = 0; i < posList.Count; i++) { Vector3 point = posList[i]; if (useArcing) { Vector3 v = new Vector3(); if (X) v.x = Arcing(i); if (Y) v.y = Arcing(i); if (Z) v.z = Arcing(i); point = Vector3.Lerp(posList[i], posList[i] + v, fps); } if (useSine && i != 0 && i != posList.Count-1) { Vector3 v = new Vector3(); if (X) v.x = Sine(i + sineRandom); if (Y) v.y = Sine(i + sineRandom); if (Z) v.z = Sine(i + sineRandom); point += v; } if (useWiggle && i != 0 && i != posList.Count - 1) point += Wiggle(i); list.Add(point); } SetLinePosition(list); } void SetLinePosition(List<Vector3> listPoint) { lineRenderer.positionCount = listPoint.Count; for(int i = 0; i < listPoint.Count; i++) { lineRenderer.SetPosition(i, listPoint[i]); } } public void LerpPos() { int index = PosSize + 2; for(int i=0; i < index; i++) { if (posList.Count < index) posList.Add(Vector3.Lerp(startPos, endPos, (float)i / index)); else posList[i] = Vector3.Lerp(startPos, endPos, (float)i / index); } } float Arcing(float param) { return _ArcingPowParam1 * Mathf.Pow((param - (float)posList.Count / 2 + _CenterOffset) * _ArcingPowParam1,2) + _Adjust; } float Sine(float param) { return Mathf.Sin((float)param / posList.Count * 2 * 3.14f * _SineScaleX) * _SineScaleY; } Vector3 Wiggle(int listIndex) { Vector3 v = new Vector3(); if (X) v.x = Random.Range(0, 10) * _RandomSize; if (Y) v.y = Random.Range(0, 10) * _RandomSize; if (Z) v.z = Random.Range(0, 10) * _RandomSize; return v; } } 

 

小讯
上一篇 2025-03-17 23:14
下一篇 2025-01-24 10:41

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/13738.html