1. 程式人生 > >unity關於lineRender平滑畫線問題

unity關於lineRender平滑畫線問題

使用lineRender的時候需要在攝像機上加上元件linerender 可以調節粗細顏色之類

可以簡單下面方法測試

	void Start () {
		lineRenderer = gameObject.GetComponent<LineRenderer>(); 

		lineRenderer.SetVertexCount(5);
	}

    void Update () {
        lineRenderer.SetPosition (0, new Vector3 (-1, 1, 0));
        lineRenderer.SetPosition (1, new Vector3 (1, 1, 0));
        lineRenderer.SetPosition (2, new Vector3 (1, -1, 0));
        lineRenderer.SetPosition (3, new Vector3 (-1, -1, 0));
        lineRenderer.SetPosition (4, new Vector3 (-1, 1, 0));
        }

 
可能畫面裡面看不到,因為在元件上沒有材質
一定要加sprite/default之類的材質的材質  不然可能看不見或者視覺效果不正常


下面是簡單畫線程式碼

public class drawLine : MonoBehaviour {
	LineRenderer lineRenderer;
	int i = 0;
	void Start () {
		lineRenderer = gameObject.GetComponent<LineRenderer>(); 
	}
	void Update () {

		if(Input.GetMouseButton(0)) 
		{ 
			i++;
			lineRenderer.SetVertexCount(i); 
			lineRenderer.SetPosition(i-1,Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,Input.mousePosition.y,10))); 
		}
	}
}
但是可以發現嚴重的問題就是有鋸齒,所以這裡最好用Vectrosity來解決

可以使用這裡的

http://blog.csdn.net/taotaoah/article/details/50607444

可以在drawlinestouch的例子上加line.joins = Joins.Weld;

但是Vectrosity是使用另一個攝像機的,所以要截圖的比較困難

所以下面要用的是貝塞爾曲線方式

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class BezierPath
{
	public List<Vector3> pathPoints;
	private int segments;
	public int pointCount;
	
	public BezierPath()
	{
		pathPoints = new List<Vector3>();
		pointCount = 100;//最大點數
	}
	
	public void DeletePath()
	{
		pathPoints.Clear ();
	}
	//t就是兩點之間幾分之幾的位置
	Vector3 BezierPathCalculation(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, float t)
	{	
		float tt = t * t;
		float ttt = t * tt;
		float u = 1.0f - t;
		float uu = u * u;
		float uuu = u * uu;
		
		Vector3 B = new Vector3();
		B = uuu * p0;
		B += 3.0f * uu * t * p1;
		B += 3.0f * u * tt * p2;
		B += ttt * p3;

		return B;
	}
	
	public List<Vector3> CreateCurve(List<Vector3> controlPoints)
	{
		segments = controlPoints.Count / 3;//以3為間隔進行平滑 算出分段數量
		pointCount = controlPoints.Count;//這裡最大點數就是本身
		for (int s = 0; s < controlPoints.Count -3; s+=3)//以3為間隔遍歷所有點
		{
			Vector3 p0 = controlPoints[s];
			Vector3 p1 = controlPoints[s+1];
			Vector3 p2 = controlPoints[s+2]; 
			Vector3 p3 = controlPoints[s+3];
			//第一個點的處理
			if(s == 0)
			{
				pathPoints.Add(BezierPathCalculation(p0, p1, p2, p3, 0.0f));
			}    
			//
			for (int p = 0; p < (pointCount/segments); p++) 
			{
				float t = (1.0f / (pointCount/segments)) * p;
				Vector3 point = new Vector3 ();
				point = BezierPathCalculation (p0, p1, p2, p3, t);
				pathPoints.Add (point);
			}
		}
		return pathPoints;
	}
}

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DrawLine : MonoBehaviour {
	
	// Use this for initialization
	
	private List<Vector3> list;
	private bool IsDraw = false;
	private LineRenderer lineRenderer;



	void Start () {
		lineRenderer = gameObject.GetComponent<LineRenderer>();
	}
	
	// Update is called once per frame
	void Update()
	{
		
		if (Input.GetMouseButtonDown(1))
		{
			if (list == null)
				list = new List<Vector3>();
			
			list.Clear();
			IsDraw = true;
			lineRenderer.SetVertexCount(0);

		}
		if (Input.GetMouseButton(1))
		{
			list.Add(Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,Input.mousePosition.y,10)));
		}
		
		if (Input.GetMouseButtonUp(1))
		{
			IsDraw = false;
		}



		drawBezierCurve();
		//drawInputPointCurve();
		
	}
	
	private void drawBezierCurve()
	{
		if(IsDraw&&list.Count>0){
			List<Vector3> bcList;
//			BezierCurve bc= new BezierCurve();
			BezierPath bc= new BezierPath();

			//bcList = bc.CreateCurve(list);//  通過貝塞爾曲線 平滑
			bcList = bc.CreateCurve(list);//  通過貝塞爾曲線 平滑

			lineRenderer.SetVertexCount(bcList.Count); 
			for (int i = 0; i < bcList.Count; i++)
			{
				Vector3 v = bcList[i];
				v += new Vector3(0, 0.5f, 0);
				lineRenderer.SetPosition(i, v);
			}
			
		}
		
	}
	//普通沒有使用貝塞爾的情況
	private void drawInputPointCurve()
	{
		if (IsDraw && list.Count > 0)
		{
			lineRenderer.SetVertexCount(list.Count);
			for (int i = 0; i < list.Count; i++)
			{
				Vector3 v = list[i];
				v += new Vector3(0, 0.5f, 0);
				lineRenderer.SetPosition(i, v);
			}
			
		}
	}
}

可以看到圖片那種鋸齒會少很多,當然還有很多改進的地方,比如加上抗鋸齒啊,使用貼圖或者rendertexture之類

但是由於專案不同,不是每個方法都能用,要看自己斟酌

最後吐糟下unity的linerenderer,也沒有2D版的,沒法設定corner或者joint

其實還有的方法就是放棄unity自帶的linerenderer而使用自己寫mesh的方式進行,這樣可以更好平滑