利用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++;
        }
    }
}

全文完

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