Unity - 製作電流效果1 - LineRenderer

  在表現電流效果上想要華麗又漂亮當然是可以靠美術的圖,但是當沒有這個資源的時候,其實用簡單的一張光束圖加上亂數跑來跑去的座標點,也是勉強可以做出堪用的電流效果。




  使用Unity內建的LineRenderer就可以做出簡單的電流效果,概念就是取得起始點跟目標點的位置,在這段路徑上切割數個節點,調整節點的位置,再把各個節點線段連起來就可以得到一個模擬電流的效果。

  開始先設定好LineRenderer的節點數量SetVertexCount(),之後每個frame就是用SetPosition()來調整每個點偏移的量,剩下的部分就交給LineRenderer去完成了。

  使用LineRenderer雖然很方便,但是也有不少問題存在,例如這一整條線段是連續的,想要有另一條線段就要再一個LineRenderer,這也帶出另一個問題,LineRenderer產生的線段資料沒有batching,所以一條線段就要用一個Draw Call,用十個LineRenderer製作十條線就會吃10個Draw Call,所以如果要用這個來模擬電流效果就需要注意使用的數量。


--
實作測試:單次電流跟連續電流,滑鼠點選場景中球球可拖曳。




--
使用LineRenderer的電流
public class Electric : MonoBehaviour
{
    public Material mat; //材質
    public GameObject target; //電流要打向的目標
    public int count = 15; //線段的節點數
    public float startWidth = 0.1f; //線段開始的寬度
    public float endWidth = 0.1f; //線段結束的寬度
    private LineRenderer lineRender;

    void Start () {
        //初始設定LineRenderer
        lineRender = this.gameObject.AddComponent (typeof(LineRenderer)) as LineRenderer;
        lineRender.material = mat;
        lineRender.SetVertexCount (count);
        lineRender.SetWidth (startWidth, endWidth);
    }
 
    void Update () {
        Lightning();
    }

    private void Lightning()
    {
        Vector3 dir = target.transform.position - this.transform.position;
        Vector3 dirDelta = dir / (count - 1); //取得切分後一段的長度
        float theta = Mathf.Atan2 (dirDelta.y, dirDelta.x);

        for(int i = 0; i < count; ++i)
        {
            Vector3 pos = this.transform.position + dirDelta * i; //每條線段的開始點座標

            int mid = count / 2;
            float ratio = (count % 2 == 0) ? (i - (i/mid) * ((i % mid + 1)*2 - 1)) : (i - (i/(mid+1)) * ((i % (mid+1) + 1)*2));
            //調整比率讓線段兩端變動小,中央變動大,使電流形狀產生菱形的感覺

            float r1 = Random.Range(-0.06f, 0.06f) * ratio;
            float r2 = Random.Range(-0.12f, 0.12f) * ratio;

            Vector3 dir1 = new Vector3(Mathf.Cos (theta) * r1, Mathf.Sin(theta) * r1, 0);
            Vector3 dir2 = new Vector3(Mathf.Sin (theta) * r2, -Mathf.Cos(theta) * r2, 0);
            Vector3 targetPos = pos + dir1 + dir2;
            //角度調整參數,讓電流菱形的效果不會因為電流起始跟終點位置改變而造成形狀改變

            lineRender.SetPosition(i, targetPos);
        }
    }
}


No comments:

Post a Comment