小言_互联网的博客

Unity 利用LineRenderer组件实现UGUI闪电链跟随手指特效

533人阅读  评论(0)

首先,大家伙儿先认真看一下这些大佬博主写的3D版的闪电链特效,我们的UGUI的闪电链特效就是基于这些博主的方案上修改优化。
https://jingyan.baidu.com/article/f54ae2fc7731171e92b849d7.html

首先我们要把UI的模式转为摄像机,这个方案是必须的
除非你只需要特效,不显示其它UI了,
你想要闪电链特效在其它UI上,那么你就要这样做

将LineRender的层级调整一下即可

效果:


获得鼠标世界坐标脚本

_position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10));

完整脚本:注意作者的StartPosition已经没有了任何意义,自己修改一下

using System.Collections.Generic;

using UnityEngine;

[RequireComponent(typeof(LineRenderer))]

//[ExecuteInEditMode]  //普通的类,加上ExecuteInEditMode, 就可以在编辑器模式中运行

public class ChainLightning : MonoBehaviour
{
   

    public float detail = 1;//增加后,线条数量会减少,每个线条会更长。  

    public float displacement = 15;//位移量,也就是线条数值方向偏移的最大值  

    public Transform EndPostion;//链接目标  

    public Transform StartPosition;

    public float yOffset = 0;

    private LineRenderer _lineRender;

    private List<Vector3> _linePosList;

    private Vector3 _position;

    private void Awake()

    {
   
        _lineRender = GetComponent<LineRenderer>();

        _linePosList = new List<Vector3>();
    }

    private void Update()

    {
   

        //判断是否暂停,未暂停则进入分支

        if (Time.timeScale != 0)
        {
   

            _linePosList.Clear();

            Vector3 startPos = Vector3.zero;

            Vector3 endPos = Vector3.zero;

            if (EndPostion != null)

            {
   

                endPos = EndPostion.position + Vector3.up * yOffset;

            }

            if (StartPosition != null)

            {
   
                if (Input.GetMouseButton(0))
                {
   
                #if UNITY_EDITOR
                    _position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 10));
                #else
                    if (Input.touchCount <= 0)
                    {
   
                        return;
                    }   
                    _position = Camera.main.ScreenToWorldPoint(new Vector3(Input.GetTouch(0).position.x, Input.GetTouch(0).position.y, 10));
                #endif
                    //Debug.Log("鼠标坐标:==== " + _position);
                    startPos = _position + Vector3.up * yOffset;
                }
                
                
                //startPos = StartPosition.position + Vector3.up * yOffset;

            }

            //获得开始点与结束点之间的随机生成点

            CollectLinPos(startPos, endPos, displacement);

            _linePosList.Add(endPos);

            //把点集合赋给LineRenderer

            _lineRender.positionCount = _linePosList.Count;

            for (int i = 0, n = _linePosList.Count; i < n; i++)

            {
   

                _lineRender.SetPosition(i, _linePosList[i]);

            }

        }

    }

    //收集顶点,中点分形法插值抖动  

    private void CollectLinPos(Vector3 startPos, Vector3 destPos, float displace)

    {
   

        //递归结束的条件

        if (displace < detail)

        {
   

            _linePosList.Add(startPos);

        }

        else

        {
   

            float midX = (startPos.x + destPos.x) / 2;

            float midY = (startPos.y + destPos.y) / 2;

            float midZ = (startPos.z + destPos.z) / 2;

            midX += (float)(UnityEngine.Random.value - 0.5) * displace;

            midY += (float)(UnityEngine.Random.value - 0.5) * displace;

            midZ += (float)(UnityEngine.Random.value - 0.5) * displace;

            Vector3 midPos = new Vector3(midX, midY, midZ);

            //递归获得点

            CollectLinPos(startPos, midPos, displace / 2);

            CollectLinPos(midPos, destPos, displace / 2);

        }

    }

}

总结:
其实相比链接上的,你只需要把3D物体换成UI
将Canvas的渲染模式调整为摄像机
将拖尾组件的层级调整一下即可


转载:https://blog.csdn.net/lq1340817945/article/details/116275403
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场