Unity开发绘画板——04.笔刷大小调节
笔刷大小调节
上面的代码中其实我们已经提供了笔刷大小的字段,即brushSize,现在只需要将该字段和界面中的Slider绑定即可,Slider值的范围我们设置为1~20
代码中只需要做如下改动:
public Slider brushSizeSlider; //控制笔刷大小的滑动条
public float brushSize => brushSizeSlider.value; //笔刷大小取滑动条的值
完整代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Painter : MonoBehaviour
{
public RenderTexture renderTexture;
public Slider brushSizeSlider;
public Texture2D brushTexture; //笔刷纹理
public float brushSize => brushSizeSlider.value; //笔刷大小
public float resolutionMultiplier = 5; //线性插值密度调节
private Vector2 previousMousePos; //记录上一帧鼠标的位置
void Update()
{
if (Input.GetMouseButtonDown(0))
{
previousMousePos = Input.mousePosition;
}
if (Input.GetMouseButton(0))
{
var mousePosition = Input.mousePosition;
DrawLine(previousMousePos, mousePosition);
previousMousePos = mousePosition;
}
}
private void DrawLine(Vector2 start, Vector2 end)
{
float distance = Vector2.Distance(start, end);
int steps = Mathf.CeilToInt(distance * resolutionMultiplier);
for (int i = 0; i <= steps; i++)
{
float t = i / (float)steps;
int x = Mathf.FloorToInt(Mathf.Lerp(start.x, end.x, t));
int y = Mathf.FloorToInt(Mathf.Lerp(start.y, end.y, t));
DrawBrush(x, y);
}
}
private void DrawBrush(int x, int y)
{
Rect brushRect = new Rect(x, y, brushSize, brushSize);
Graphics.SetRenderTarget(renderTexture);
GL.PushMatrix();
GL.LoadPixelMatrix(0, renderTexture.width, 0, renderTexture.height);
Graphics.DrawTexture(brushRect, brushTexture);
GL.PopMatrix();
Graphics.SetRenderTarget(null);
}
}
效果优化
运行效果如下图,可见虽然笔刷粗细已可以调节,但是在调节过程中,滑动的同时滑动条周围有绘制的线条,这本不该出现的,出现的原因是因为我们监听了鼠标按下的事件来绘制,这导致在操作滑动条的时候,绘制依然在进行。
操作UI时屏蔽绘制
我们需要检测当前的鼠标是否在UI元素上,如果在,则不进行绘制,这可以使用EventSystem的射线检测来实现,如下我们定义一个函数,当光标在UI元素上的时候返回true,否则返回false:
private bool IsPointerOverUIElement()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
return results.Count > 0;
}
我们在鼠标左键点击的时候判断是否在UI元素上,如果在则禁止绘制;
但有个问题,我们用来绘制的RawImage也是UI元素,它铺满整个屏幕,这会导致我们始终没办法绘制,我们可以将其Raycast Target关掉,这样再操作UI元素的时候就不会进行多余的绘制了
完整代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Painter : MonoBehaviour
{
public RenderTexture renderTexture;
public Slider brushSizeSlider; //控制笔刷大小的滑动条
public Texture2D brushTexture; //笔刷纹理
public float brushSize => brushSizeSlider.value; //笔刷大小取滑动条的值
public float resolutionMultiplier = 5; //线性插值密度调节
private Vector2 previousMousePos; //记录上一帧鼠标的位置
private bool startFromUIElement = false; //点击是否是从UI元素上开始的
void Update()
{
//判断光标是否在UI元素上
if (Input.GetMouseButtonDown(0))
{
if (IsPointerOverUIElement())
{
startFromUIElement = true;
}
previousMousePos = Input.mousePosition;
}
if (Input.GetMouseButton(0) && !startFromUIElement)
{
var mousePosition = Input.mousePosition;
DrawLine(previousMousePos, mousePosition);
previousMousePos = mousePosition;
}
if (Input.GetMouseButtonUp(0))
{
startFromUIElement = false;
}
}
private void DrawLine(Vector2 start, Vector2 end)
{
float distance = Vector2.Distance(start, end);
int steps = Mathf.CeilToInt(distance * resolutionMultiplier);
for (int i = 0; i <= steps; i++)
{
float t = i / (float)steps;
int x = Mathf.FloorToInt(Mathf.Lerp(start.x, end.x, t));
int y = Mathf.FloorToInt(Mathf.Lerp(start.y, end.y, t));
DrawBrush(x, y);
}
}
private void DrawBrush(int x, int y)
{
Rect brushRect = new Rect(x, y, brushSize, brushSize);
Graphics.SetRenderTarget(renderTexture);
GL.PushMatrix();
GL.LoadPixelMatrix(0, renderTexture.width, 0, renderTexture.height);
Graphics.DrawTexture(brushRect, brushTexture);
GL.PopMatrix();
Graphics.SetRenderTarget(null);
}
private bool IsPointerOverUIElement()
{
PointerEventData eventData = new PointerEventData(EventSystem.current);
eventData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventData, results);
return results.Count > 0;
}
}
在下一节我将为大家介绍如何调节线条的颜色~