之前简单看过一下GL画线,由于适配问题,未能实现,后面有时间在看一下具体原因,今天以重绘像素的方式实现了画线,由于算法不好,会有卡顿,后面会继续优化。
这个画线功能,是以RawImage实现的。
首先获取RawImage和RectTransform:
rawImage = GetComponent<RawImage>();
rectTransform = rawImage.GetComponent<RectTransform>();
然后进行RawImage的初始化:
Vector3 pos = rectTransform.position ;
texture = new Texture2D((int)rectTransform.sizeDelta.x, (int)rectTransform.sizeDelta.y);
Clear();
rawImage.texture = texture;
public void Clear()
{
int x, y;
for (x = 0; x < texture.width; x++)
{
for (y = 0; y < texture.height; y++)
{
texture.SetPixel(x, y, Color.white);
}
}
texture.Apply();
}
获取偏移量:
Vector3 posOffset3d = transform.position - transform.root.position;
posOffset = new Vector2(posOffset3d.x + (Screen.width - rectTransform.sizeDelta.x) / 2, posOffset3d.y + (Screen.height - rectTransform.sizeDelta.y) / 2);
下面进行绘制:
private void Draw(Vector2 position, int sideLength)
{
int x, y;
for (y = 0 - sideLength; y < sideLength; y++)
{
for (x = 0 - sideLength; x < sideLength; x++)
{
if (isEraser == true)
{
texture.SetPixel((int)position.x - x, (int)position.y - y, Color.white);
}
else
{
texture.SetPixel((int)position.x - x, (int)position.y - y, brushColor);
}
}
}
texture.Apply();
}
private void DrawLerp(Vector2 pos)
{
if (isBegin == false)
{
isBegin = true;
previousPosition = pos;
}
distance.Set(pos.x - previousPosition.x, pos.y - previousPosition.y);
float length = Mathf.Sqrt(distance.x * distance.x + distance.y * distance.y);
int interval = brushSize < 2 ? 1 : brushSize / 2;
int num = (int)length / interval;
float d_x = (distance.x / num);
float d_y = (distance.y / num);
float p_x = (previousPosition.x);
float p_y = (previousPosition.y);
if (length > interval)
{
for (int i = 1; i < num; i++)
{
float v_x = p_x + d_x * i;
float v_y = p_y + d_y * i;
Draw(new Vector2(v_x, v_y), brushSize);
}
}
else
{
Draw(pos, brushSize);
}
previousPosition = pos;
}
完整代码如下(触发判断为自己写的功能):
using UnityEngine;
using UnityEngine.UI;
using LastZero.Event;
namespace LastZero
{
public class Drawing: MonoBehaviour {
public Color brushColor;//画笔颜色
public int brushSize = 1;//画笔宽度
private RawImage rawImage;//画图所用图片
private RectTransform rectTransform;//RrectTransform
private Texture2D texture;//贴图
private Color colorBackGround;//背景色
private bool isCanDraw;//是否可以画图
private Vector2 posOffset;//偏移
private bool isEraser;//是否使用橡皮擦
private bool isBegin = false;//是否开始
private Vector2 previousPosition;//旧坐标
private Vector2 distance;//新旧点的距离
private void Awake()
{
rawImage = GetComponent<RawImage>();
rectTransform = rawImage.GetComponent<RectTransform>();
}
private void Start()
{
RawImageInit();
colorBackGround = rawImage.color;
isCanDraw = false;
Setoffset();
DrawController();
}
/// <summary>
/// RawImage初始化
/// </summary>
private void RawImageInit()
{
Vector3 pos = rectTransform.position ;
texture = new Texture2D((int)rectTransform.sizeDelta.x, (int)rectTransform.sizeDelta.y);
Clear();
rawImage.texture = texture;
}
private void Setoffset()
{
Vector3 posOffset3d = transform.position - transform.root.position;
posOffset = new Vector2(posOffset3d.x + (Screen.width - rectTransform.sizeDelta.x) / 2, posOffset3d.y + (Screen.height - rectTransform.sizeDelta.y) / 2);
}
/// <summary>
/// 清空
/// </summary>
public void Clear()
{
int x, y;
for (x = 0; x < texture.width; x++)
{
for (y = 0; y < texture.height; y++)
{
texture.SetPixel(x, y, Color.white);
}
}
texture.Apply();
}
/// <summary>
/// 绘制控制
/// </summary>
private void DrawController()
{
Vector2 pos = new Vector2();
gameObject.AddEnterEvent(delegate {
isCanDraw = true;
});
gameObject.AddExitEvent(delegate {
isCanDraw = false;
isBegin = false;
});
gameObject.AddDrugEvent(delegate
{
if (!isCanDraw)
return;
pos.Set(Input.mousePosition.x - posOffset.x, Input.mousePosition.y - posOffset.y);
DrawLerp(pos);
});
gameObject.AddEndDrugEvent(delegate
{
isBegin = false;
});
}
/// <summary>
/// 方形
/// </summary>
/// <param name="position"></param>
/// <param name="sideLength"></param>
private void Draw(Vector2 position, int sideLength)
{
int x, y;
for (y = 0 - sideLength; y < sideLength; y++)
{
for (x = 0 - sideLength; x < sideLength; x++)
{
if (isEraser == true)
{
texture.SetPixel((int)position.x - x, (int)position.y - y, Color.white);
}
else
{
texture.SetPixel((int)position.x - x, (int)position.y - y, brushColor);
}
}
}
texture.Apply();
}
private void DrawLerp(Vector2 pos)
{
if (isBegin == false)
{
isBegin = true;
previousPosition = pos;
}
distance.Set(pos.x - previousPosition.x, pos.y - previousPosition.y);
float length = Mathf.Sqrt(distance.x * distance.x + distance.y * distance.y);
int interval = brushSize < 2 ? 1 : brushSize / 2;
int num = (int)length / interval;//将间距切割成固定片段,并在每个片段打点
float d_x = (distance.x / num);
float d_y = (distance.y / num);
float p_x = (previousPosition.x);
float p_y = (previousPosition.y);
if (length > interval)
{
for (int i = 1; i < num; i++)
{
float v_x = p_x + d_x * i;
float v_y = p_y + d_y * i;
Draw(new Vector2(v_x, v_y), brushSize);
}
}
else
{
Draw(pos, brushSize);
}
previousPosition = pos;
}
}
}