Reputation: 147
I want to write a simple "point painting" code.
I have created a script which was supposed to instantiate gameobject (point) according to mouse position, but there is a 5 clone instead of 1, in a one mouse click.
void Update()
{
if (Input.GetMouseButton(0))
{
Vector3 newPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
newPos.z = 0;
Instantiate(prefab, newPos, Quaternion.identity);
}
}
how can I play with instantiate speed in update method?
or
how can I make list (ArrayList) of instantiated objects and then destroy objects (points) which has a same position?
Upvotes: 1
Views: 175
Reputation: 4056
You can try this: Paint when the mouse cursor travels a certain amount of distance, like so:
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;
}
}
Basically, it starts painting OnMouseDown
.
When the mouse cursor travels a certain amount of distance (paintDistanceThreshold
), it will paint another object.
Stops painting OnMouseUp
.
Though one issue you might encounter is that when your mouse cursor intercepts a point where you have painted before, it will paint on that point again.
can I make list (ArrayList) of instantiated objects and then destroy objects (points) which has a same position?
It will mostly work if your painter is pixel/grid based. Otherwise, the coordinates needs to be rounded off for it to work accurately.
That said, most painting applications today uses pixel-based. I would highly suggest that you make your painter paint by pixel/grid rather than world coordinates.
This way, you can avoid a lot of the issues that I mentioned earlier.
Upvotes: 1
Reputation: 7007
The problem here is that u are using Input.GetMouseButton(0)
which will return true in every frame while the left mouse button is held down(your machine basically is so fast that while you as a human only did a simple mouse press, your computer actually rendered 5 frames thus the 5 instatiation), in order to prevent this use Input.GetMouseButtonDown(0)
, which will only return true in one frame specifically when the left mouse button is pressed.
Here are the mouse button events that might be useful for you:
Returns true during the frame the user pressed the given mouse button.
Input.GetMouseButtonDown(int button);
Returns whether the given mouse button is held down or not.
Input.GetMouseButton(int button);
Returns true during the frame the user releases the given mouse button.
Input.GetMouseButtonUp(int button);
Upvotes: 1