用unity实现动态粒子效果(上)【详细】

最近我在Wallpaper Engine上法线了一款有趣的壁纸,
不放音乐的时候
在这里插入图片描述
当音乐响起的时候
在这里插入图片描述
然后我就想,这个如何用Unity实现,我们先来观察,便面上每个点的运动毫无规律,实际上它们每个点都有自己的方向,当点到达屏幕边缘时,反弹;当音乐响起时,它只会随着音乐的节奏加速运动和放大,它的运动轨迹并没有变化;当相邻的两个点足够近的时候连接,足够远就断开。好了分析到这里,案子已经结了。
我们首先来实现它的运动部分和连接部分,音乐响应部分会在(下)篇来实现。

我们首先针对一个点来做:
在start的时候,给这个点一个随机的位置和一个随机的方向

		thispoint = this.transform;
        thispoint.position = new Vector2(Random.Range(-9.0f, 9.0f), Random.Range(-5.0f, 5.0f));
        way = new Vector2(Random.Range(0.0f,1.0f), Random.Range(0.0f, 1.0f));

在fixedupdate函数中,让这个点保持一定的速度,朝着这个方向运动

 private void FixedUpdate()
    {
        thispoint.Translate(way * gamectrl.speed*Time.fixedDeltaTime);
       
    }

在update函数中,我们判断这个点是不是碰撞到了屏幕边缘,如果碰撞了,我们需要做的就是计算它的反弹方向,并把这个方向赋给二维方向变量way

private void Update()
    {
         checkside();
     }
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;
            }
            else if (thispoint.position.x <= -9)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(-1, 0)) * new Vector2(-1, 0) + way).normalized;
            }
            else if (thispoint.position.y >=5)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(0, -1)) * new Vector2(0, -1) + way).normalized;
            }
            else if (thispoint.position.y <= -5)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(0, 1)) * new Vector2(0,1) + way).normalized;
            }
        }
    }

那么到现在,我们关于一个点的运动已经完成了
在这里插入图片描述

好,现在我们来完成点与点的连接,首先我们需要给这个点添加‘’碰撞器‘’和‘’线段渲染器‘’,我们需要碰撞器来判断什么时候连什么时候断,用线段渲染器来画线。
首先建立一个泛型,来管理这个点周围的点

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

当碰撞器碰撞的时候,触发OnCollisionEnter2D事件,在各个事件中我们把碰撞到的点添加到泛型中;当有点离开碰撞器范围之后,触发OnCollisionExit2D时间,把这个点从泛型中移出去。

 private void OnCollisionEnter2D(Collision2D collision)
    {
        points.Add(collision.transform);
    }
    private void OnCollisionExit2D(Collision2D 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);
        }

现在,运行效果如下:
在这里插入图片描述

因为电工实验考试的原因,我可能会在考完试之后再更新(下)关于受音频相应和特效美化的部分,所以这个暂时鸽了,有的同学说我关于【用Unity做图像处理软件】系列写的不够详细,我也听取了,我感觉这次写得应该算是比较详细了。。。
下面附上目前所有的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public struct gamectrl
{
    public static float speed = 10;
}
public class moveforall : 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;
        thispoint.position = new Vector2(Random.Range(-9.0f, 9.0f), Random.Range(-5.0f, 5.0f));
        way = new Vector2(Random.Range(0.0f,1.0f), Random.Range(0.0f, 1.0f));
        way = way.normalized;
        LR.SetVertexCount(30);
        LR.SetWidth(.06f, .06f);
	}

    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;
            }
            else if (thispoint.position.x <= -9)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(-1, 0)) * new Vector2(-1, 0) + way).normalized;
            }
            else if (thispoint.position.y >=5)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(0, -1)) * new Vector2(0, -1) + way).normalized;
            }
            else if (thispoint.position.y <= -5)
            {
                way = (2 * Vector2.Dot(-way, new Vector2(0, 1)) * new Vector2(0,1) + way).normalized;
            }
        }
    }
    private void OnCollisionEnter2D(Collision2D collision)
    {
        points.Add(collision.transform);
    }
    private void OnCollisionExit2D(Collision2D 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++;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_33967521/article/details/84535815