廢話不多直接上結果,如果需要的是這種結果的話,請跟我一步步做完以下步驟,沒有耐心可以直接看代碼
下面就簡單介紹一下思路
需求分析
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++;
}
}
}
全文完