我想编写一个简单的“点画”代码。
我创建了一个脚本,该脚本应该根据鼠标位置来实例化游戏对象(点),但是单击一次鼠标后,将有5个克隆而不是1个克隆。
void Update()
{
if (Input.GetMouseButton(0))
{
Vector3 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
newPos.z = 0;
Instantiate(prefab, newPos, Quaternion.identity);
}
}
如何在更新方法中以实例化的速度播放?
或
如何创建实例化对象的列表(ArrayList),然后销毁具有相同位置的对象(点)?
答案 0 :(得分:1)
这里的问题是,您使用Input.GetMouseButton(0)
时,在按住鼠标左键的同时,每帧都将返回true(您的机器基本上是如此之快,以至于您作为人类只需要简单地按一下鼠标键,则您的计算机实际上渲染了5帧,因此实际渲染了5个实例),以防止这种使用Input.GetMouseButtonDown(0)
,特别是在按下鼠标左键时,它只会在一帧中返回true。
以下是可能对您有用的鼠标按钮事件:
在用户按下给定鼠标按钮的帧期间返回true。
Input.GetMouseButtonDown(int button);
返回是否按住给定的鼠标按钮。
Input.GetMouseButton(int button);
在用户释放给定鼠标按钮的帧期间返回true。
Input.GetMouseButtonUp(int button);
答案 1 :(得分:1)
您可以尝试以下操作:当鼠标光标移动一定距离时进行绘制,如下所示:
public class MyPainter : MonoBehaviour {
[SerializeField, Tooltip("The prefab to paint")]
private GameObject toPaint;
[SerializeField, Tooltip("How far does the cursor have to move in order to paint the next object?")]
private float paintDistanceThreshold;
private bool isPainting;
/// <summary>
/// How much distance did the cursor travelled since last paint.
/// </summary>
private float cursorDistanceTravelledSinceLastPaint;
private Vector2 lastCursorPosition;
private Camera mainCameraRef;
private void Awake() {
isPainting = false;
// Btw, cache the main camera. Repeated calls to 'Camera.main' is expensive.
mainCameraRef = Camera.main;
cursorDistanceTravelledSinceLastPaint = 0f;
}
private void Update() {
// Mouse button pressed, start painting.
if (Input.GetMouseButtonDown(0)) {
PaintAtCurrentCursorPosition();
isPainting = true;
}
if (isPainting) {
cursorDistanceTravelledSinceLastPaint += Vector2.Distance(Input.mousePosition, lastCursorPosition);
if (cursorDistanceTravelledSinceLastPaint >= paintDistanceThreshold) {
PaintAtCurrentCursorPosition();
}
}
// Mouse button lifted, stop painting.
if (Input.GetMouseButtonUp(0)) {
isPainting = false;
}
lastCursorPosition = Input.mousePosition;
}
private void PaintAtCurrentCursorPosition() {
Vector3 newPos = mainCameraRef.ScreenToWorldPoint(Input.mousePosition);
newPos.z = 0;
Instantiate(toPaint, newPos, Quaternion.identity);
cursorDistanceTravelledSinceLastPaint = 0f;
}
}
基本上,它开始绘制OnMouseDown
。
当鼠标光标移动一定距离(paintDistanceThreshold
)时,它将绘制另一个对象。
停止绘画OnMouseUp
。
您可能会遇到的一个问题是,当鼠标光标截取您之前绘制的点时,它将再次在该点上绘制。
我可以列出实例化对象的列表(ArrayList),然后销毁具有相同位置的对象(点)吗?
如果您的画家是基于像素/网格的,则大多数情况下都可以使用。否则,需要四舍五入以使其正确工作。
也就是说,当今大多数绘画应用程序都基于像素。我强烈建议您使用像素/网格而不是世界坐标来制作画家的油漆。
这样,您可以避免我前面提到的许多问题。