一:在世界空间下绘制
——当每次鼠标按下时,创建一个空物体并添加LineRenderer组件,设置当前LineRenderer的各种参数
注意需要设置LineRenderer的材质Shader(必须设置可以接收颜色的Shader,比如Sprites/Default或Legacy Shaders/Particles/Alpha Blended Premultiply),否则修改颜色不起作用
——当鼠标按下中,将当前鼠标按下位置的每个点添加到LineRenderer的Positions数组中(LineRenderer对Positions数组中位置依次连线绘制)
——以上代码已经可以实现绘制线段
但是有一个可以优化的地方,现在当鼠标每次按下中,鼠标就算不动但仍然会一直向Positions数组中添加位置,造成不必要的性能消耗,所以我们可以添加一个判断,当鼠标移动了一定的距离后才向Positions数组中添加位置进行绘制线段
——完整代码(挂载到任意游戏物体身上)
using UnityEngine;
public class Draw : MonoBehaviour
{
private LineRenderer curLine;//当前实例化出来的线
private int posIndex;//当前线的Positions数组下标
private Vector2 mouseEndPos;//鼠标结束的位置
//线的参数
public Color startColor = Color.black;//线开始的颜色
public Color endColor = Color.black;//线结束的颜色
public float width = 0.1f;//线宽度
public int vertices = 90;//顶点数
/// <summary>
/// 初始化线
/// </summary>
private void InitLine()
{
posIndex = 0;
curLine.startColor = startColor;
curLine.endColor = endColor;
curLine.startWidth = width;
curLine.endWidth = width;
curLine.numCapVertices = vertices;
curLine.numCornerVertices = vertices;
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
curLine = new GameObject("line").AddComponent<LineRenderer>();
curLine.material = new Material(Shader.Find("Sprites/Default"));
InitLine();
}
if (Input.GetMouseButton(0))
{
Vector3 mouseStartPos = GetMousePosInWorldSpace();
//优化性能
if (Vector2.Distance(mouseStartPos, mouseEndPos) >= 0.1f)
{
AddPositions(mouseStartPos);
}
}
}
/// <summary>
/// 将线段添加到当前线的Positions数组中
/// </summary>
private void AddPositions(Vector2 pos)
{
curLine.positionCount = ++posIndex;
curLine.SetPosition(posIndex - 1, pos);
mouseEndPos = pos;
}
/// <summary>
/// 得到鼠标在世界空间下的坐标
/// </summary>
/// <returns></returns>
private Vector2 GetMousePosInWorldSpace()
{
Vector3 worldPos = Camera.main.ScreenToWorldPoint(
new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));
return worldPos;
}
}
二:在UI上绘制(可以指定画布区域绘制)
——将Canvas的渲染模式改为Screen Space-Camera并指定渲染的相机
——通过UGUI的事件系统进行绘制
——完整代码(挂载到可以绘制的画布物体上,不是Canvas根物体)
using UnityEngine;
using UnityEngine.EventSystems;
public class Draw : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
private LineRenderer curLine;//当前实例化出来的线
private int posIndex;//当前线的Positions数组下标
private Vector2 mouseEndPos;//鼠标结束的位置
//线的参数
public Color startColor = Color.black;//线开始的颜色
public Color endColor = Color.black;//线结束的颜色
public float width = 0.1f;//线宽度
public int vertices = 90;//顶点数
private bool withinCanvas;//是否在画布里
private void Update()
{
if (curLine != null && withinCanvas)
{
Vector3 mouseStartPos = GetMousePosInWorldSpace();
if (Vector2.Distance(mouseStartPos, mouseEndPos) >= 0.1f)
{
AddPositions(mouseStartPos);
}
}
}
/// <summary>
/// 初始化线
/// </summary>
private void InitLine()
{
posIndex = 0;
curLine.startColor = startColor;
curLine.endColor = endColor;
curLine.startWidth = width;
curLine.endWidth = width;
curLine.numCapVertices = vertices;
curLine.numCornerVertices = vertices;
}
/// <summary>
/// 将线段添加到当前线的Positions数组中
/// </summary>
private void AddPositions(Vector2 pos)
{
curLine.positionCount = ++posIndex;
curLine.SetPosition(posIndex - 1, pos);
mouseEndPos = pos;
}
/// <summary>
/// 得到鼠标在世界空间下的坐标
/// </summary>
/// <returns></returns>
private Vector2 GetMousePosInWorldSpace()
{
Vector3 worldPos = Camera.main.ScreenToWorldPoint(
new Vector3(Input.mousePosition.x, Input.mousePosition.y, -Camera.main.transform.position.z));
return worldPos;
}
public void OnPointerEnter(PointerEventData eventData)
{
withinCanvas = true;
}
public void OnPointerExit(PointerEventData eventData)
{
withinCanvas = false;
}
public void OnPointerDown(PointerEventData eventData)
{
curLine = new GameObject("line").AddComponent<LineRenderer>();
curLine.material = new Material(Shader.Find("Sprites/Default"));
InitLine();
}
public void OnPointerUp(PointerEventData eventData)
{
curLine = null;
}
}