vito
vito

Reputation: 147

Instantiate objects in a list

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);
    }
}

enter image description here

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

Answers (2)

WQYeo
WQYeo

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

Menyus777
Menyus777

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

Related Questions