【发布时间】:2017-12-13 10:42:36
【问题描述】:
我正在使用鼠标输入在纹理上从点 A 到点 B 绘制一条线。我意识到我并没有击中每个像素,所以将鼠标从屏幕的最左边移动到最右边,它会跳过一些值,导致间隙。当我慢慢移动鼠标时,它会变得更好。
我正在使用以下方法获取鼠标位置:
var viewPortPosition = Camera.main.ScreenToViewportPoint (Input.mousePosition);
【问题讨论】:
我正在使用鼠标输入在纹理上从点 A 到点 B 绘制一条线。我意识到我并没有击中每个像素,所以将鼠标从屏幕的最左边移动到最右边,它会跳过一些值,导致间隙。当我慢慢移动鼠标时,它会变得更好。
我正在使用以下方法获取鼠标位置:
var viewPortPosition = Camera.main.ScreenToViewportPoint (Input.mousePosition);
【问题讨论】:
如果你想画一条线,我建议你使用line renderer。假设您在 Update() 函数中实现了代码 - 这在渲染的每一帧中都会调用。所以即使你的动作很慢,显然它已经足够在你的画线中留下空隙了。
下面是来自 link 的一些代码,它应该适合你:
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class LineRendererTest : MonoBehaviour
{
List<Vector3> linePoints = new List<Vector3>();
LineRenderer lineRenderer;
public float startWidth = 1.0f;
public float endWidth = 1.0f;
public float threshold = 0.001f;
Camera thisCamera;
int lineCount = 0;
Vector3 lastPos = Vector3.one * float.MaxValue;
void Awake()
{
thisCamera = Camera.main;
lineRenderer = GetComponent<LineRenderer>();
}
void Update()
{
Vector3 mousePos = Input.mousePosition;
mousePos.z = thisCamera.nearClipPlane;
Vector3 mouseWorld = thisCamera.ScreenToWorldPoint(mousePos);
float dist = Vector3.Distance(lastPos, mouseWorld);
if(dist <= threshold)
return;
lastPos = mouseWorld;
if(linePoints == null)
linePoints = new List<Vector3>();
linePoints.Add(mouseWorld);
UpdateLine();
}
void UpdateLine()
{
lineRenderer.SetWidth(startWidth, endWidth);
lineRenderer.SetVertexCount(linePoints.Count);
for(int i = lineCount; i < linePoints.Count; i++)
{
lineRenderer.SetPosition(i, linePoints[i]);
}
lineCount = linePoints.Count;
}
【讨论】:
我最终做的是通过 Bresenham 的 Line Drawing 函数运行迄今为止收集的鼠标位置以栅格化线条。
来源:
public void line(Vector2 pointA, Vector2 pointB, Texture2D texture) {
int x = (int)pointA.x;
int y = (int)pointA.y;
int x2 = (int)pointB.x;
int y2 = (int)pointB.y;
int w = x2- x ;
int h = y2 - y;
int dx1 = 0, dy1 = 0, dx2 = 0, dy2 = 0 ;
if (w<0) dx1 = -1 ; else if (w>0) dx1 = 1 ;
if (h<0) dy1 = -1 ; else if (h>0) dy1 = 1 ;
if (w<0) dx2 = -1 ; else if (w>0) dx2 = 1 ;
int longest = Math.Abs(w) ;
int shortest = Math.Abs(h) ;
if (!(longest>shortest)) {
longest = Math.Abs(h) ;
shortest = Math.Abs(w) ;
if (h<0) dy2 = -1 ; else if (h>0) dy2 = 1 ;
dx2 = 0 ;
}
int numerator = longest >> 1 ;
for (int i=0;i<=longest;i++) {
texture.SetPixel (x, y, Color.red);
numerator += shortest ;
if (!(numerator<longest)) {
numerator -= longest ;
x += dx1 ;
y += dy1 ;
} else {
x += dx2 ;
y += dy2 ;
}
}
}
原始代码源,但针对 Unity C# 进行了修改:All cases covered Bresenham's line-algorithm
【讨论】: