利用Unity LineRender组件,复刻H5页面的绚烂Cavans点线动画(带鼠标交互)

废话不多直接上结果,如果需要的是这种结果的话,请跟我一步步做完以下步骤,没有耐心可以直接看代码

在这里插入图片描述
下面就简单介绍一下思路

需求分析
1.点随机产生并向随机方向以随机的速度匀速移动
2.点与点之间在一定距离内有细线连接,并且有淡入淡出的效果。
3.鼠标在画面中移动时,能够与其他点产生互动

1.1点的实现,如何绘制一个点?

在Js里,我们需要用代码绘制这个点,但在Unity中,我们完全可以通过预制件来完成这项工作 XD。

点的本质就是一个圆,所以我们只需要创建一个空物体,添加Canvas组件,并将Canvas UI Scale Mode设置为World Space,里面放上一张image图片,这个点就制作完毕了。但是注意,我们需要用它来做连线效果,所以我们也要给它加上LineRender组件。

1.2现在我们该让这个点动起来啦!

首先我们需要一个速度,来控制点的移动快慢

public struct gamectrl
{
    public static float speed = 0.3f;
}

其次我们需要一个init的函数,在初始化时,给这个点一个随机的位置和一个随机的方向

    void Init()
    {
        thispoint.position = new Vector2(Random.Range(-9.0f, 9.0f), Random.Range(-5.0f, 5.0f));
        way = new Vector2(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f));
        way = way.normalized;
    }

2.1在动起来的点与点之间,我们需要一根连线。

首先建立一个泛型,来管理这个点周围的点

    private List<Transform> points = new List<Transform>();

然后我们使用触发器,来在合适的时候执行连线事件,当触发器接触的时候,触发OnTriggerEnter2D事件,在各个事件中我们把碰撞到的点添加到泛型中;当有点离开碰撞器范围之后,触发OnTriggerExit2D时间,把这个点从泛型中移出去。

  private void OnTriggerEnter2D(Collider2D collision)
    {
        points.Add(collision.transform);
    }

  private void OnTriggerExit2D(Collider2D collision)
    {
        int i = 0;
        foreach (Transform ts in points)
        {

            if (collision.gameObject.name == ts.name)
            {
                if (points.Count == 1) { points.Remove(points[points.Count - 1]); return; }
                for (int n = i; n < points.Count - 1; n++)
                {
                    points[n] = points[n + 1];
                }
                points.Remove(points[points.Count - 1]);
                return;
            }
            i++;
        }
    }

我们在Update函数中处理线段,我们把list中的所有点与当前点连接起来。这里需要注意的是,要把用不到的线段处理好,比如我们设置线段节数是30,那最后把不需要用到的线段节点藏到当前点的下面( LR.SetPosition(i, thispoint.position);)。

		LR.SetPosition(0, thispoint.position);
        foreach (Transform tr in points)
        {
            LR.SetPosition(i * 2 - 1, tr.position);
            if (i == 15) break;
            LR.SetPosition(i * 2, thispoint.position);
            i++;
        }
        for (i = (i - 1) * 2; i <= 29; i++)
        {
            LR.SetPosition(i, thispoint.position);
        }

这样就完成点与点之间的连线了啦!有的小伙伴可能急眼了:“哪有!场景里根本什么都没出现~!” XDXD,那是因为此时此刻我们场景里只有一个孤零零的点,小伙伴们可以根据自己的需求,自由复制这个点在场景中(最简单的就是Ctrl+D),来控制点的数量。

2.2如何实现淡出淡入?
原则上,设置rgba颜色值可实现带透明度的颜色,透明度的计算方式为,(临界值距离 - 实际距离) / 临界值距离,这样就可以实现两点距离越远线条颜色越淡。再通过动画不停渲染,就可以造成视觉上淡入淡出的效果。

但在unity中,我们可以不使用代码,来实现这件事情
在LineRender组件中,有个Color选项,点开后有四个滑块,点击上方的两个滑块,就可以设置开端和末尾的Alpha值了。在这里插入图片描述在这里插入图片描述
3.如何实现鼠标在canvas中移动的交互效果?

思路:就是我们拎出一个点,只要将其位置与鼠标位置对齐,便可以实现这个效果了。

具体做法就是
添加一个新预制件,配置和点的内容相同,但是要使用一个新脚本用于更新需要跟踪鼠标移动的点的位置,注意隐藏掉这个预制件的圆形图片,因为鼠标并不是一个点XD

以上就是全部内容了,下面附上源码
请挂载至预制件身上的

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct gamectrl
{
    public static float speed = 0.3f;
}
public class DrawLine1 : MonoBehaviour
{
    private Transform thispoint;
    private Vector2 way;
    private LineRenderer LR;
    private List<Transform> points = new List<Transform>();
    // Use this for initialization
    void Start()
    {
        LR = this.GetComponent<LineRenderer>();
        thispoint = this.transform;
        Init();
        LR.SetVertexCount(30);
        LR.SetWidth(0.05f, 0.05f);


    }
    void Init()
    {
        thispoint.position = new Vector2(Random.Range(-9.0f, 9.0f), Random.Range(-5.0f, 5.0f));
        way = new Vector2(Random.Range(-1.0f, 1.0f), Random.Range(-1.0f, 1.0f));
        way = way.normalized;
        this.GetComponent<CircleCollider2D>().enabled = true;
    }

    private void FixedUpdate()
    {
        thispoint.Translate(way * gamectrl.speed * Time.fixedDeltaTime);
    }
    private void Update()
    {
        int i = 1;
        checkside();
        LR.SetPosition(0, thispoint.position);
        foreach (Transform tr in points)
        {
            LR.SetPosition(i * 2 - 1, tr.position);
            if (i == 15) break;
            LR.SetPosition(i * 2, thispoint.position);
            i++;
        }
        for (i = (i - 1) * 2; i <= 29; i++)
        {
            LR.SetPosition(i, thispoint.position);
        }
    }
    private void checkside()
    {
        if (Mathf.Abs(thispoint.position.x) >= 9 || Mathf.Abs(thispoint.position.y) >= 5)
        {
            if (thispoint.position.x >= 9)
            {
                // way = (2 * Vector2.Dot(-way, new Vector2(-1, 0)) * new Vector2(-1, 0) + way).normalized;
                this.GetComponent<CircleCollider2D>().enabled = false;
                Init();
            }
            else if (thispoint.position.x <= -9)
            {
                // way = (2 * Vector2.Dot(-way, new Vector2(-1, 0)) * new Vector2(-1, 0) + way).normalized;
                this.GetComponent<CircleCollider2D>().enabled = false;
                Init();
            }
            else if (thispoint.position.y >= 5)
            {
                //  way = (2 * Vector2.Dot(-way, new Vector2(0, -1)) * new Vector2(0, -1) + way).normalized;
                this.GetComponent<CircleCollider2D>().enabled = false;
                Init();
            }
            else if (thispoint.position.y <= -5)
            {
                this.GetComponent<CircleCollider2D>().enabled = false;
                Init();
              //  way = (2 * Vector2.Dot(-way, new Vector2(0, 1)) * new Vector2(0, 1) + way).normalized;
            }
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        points.Add(collision.transform);
    }


    private void OnTriggerExit2D(Collider2D collision)
    {
        int i = 0;
        foreach (Transform ts in points)
        {

            if (collision.gameObject.name == ts.name)
            {
                if (points.Count == 1) { points.Remove(points[points.Count - 1]); return; }
                for (int n = i; n < points.Count - 1; n++)
                {
                    points[n] = points[n + 1];
                }
                points.Remove(points[points.Count - 1]);
                return;
            }
            i++;
        }
    }
}

全文完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章