Home > other >  How to change the mouse radius size with mouse hold down and drag?
How to change the mouse radius size with mouse hold down and drag?

Time:01-29

The goal is when holding down the mouse left button and dragging the mouse that it will create a circle around the mouse first time click down position and then when dragging the mouse around it will resize up the circle radius on xRadius and yRadius.

For testing it I set the xRadius and yRadius to 0 at the Start()

I also added helper bool flag

private bool isMouseDown = false;

Then in Update added onm ouseDown and onm ouseDrag events

private void Update()
    {
        if (Physics.CheckSphere(transform.position, xRadius, targetLayers))
        {
            Debug.Log("player detected");
        }
        else
        {
            Debug.Log("player NOT detected");
        }
    }

    void onm ouseDown()
    {
        
    }

    void onm ouseDrag()
    {
        xRadius = xRadius   0.01f;
        yRadius = yRadius   0.01f;
        CreatePoints();
    }

but when I just hold the mouse down without any dragging yet it's changing the circle radius size. it seems that onm ouseDrag is working like when holding the mouse down even without dragging it at all.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

[ExecuteAlways]
[RequireComponent(typeof(UnityEngine.LineRenderer))]
public class DrawCircle : MonoBehaviour
{
    [Range(1, 50)] public int segments = 50;
    [Range(1, 500)] public float xRadius = 5;
    [Range(1, 500)] public float yRadius = 5;
    [Range(0.1f, 5)] public float width = 0.1f;
    [Range(0, 100)] public float height = 0;
    public bool controlBothXradiusYradius = false;
    public bool draw = true;

    [SerializeField] private LayerMask targetLayers;
    [SerializeField] private LineRenderer line;

    private bool isMouseDown = false;

    private void Start()
    {
        xRadius = 0;
        yRadius = 0;

        if (!line) line = GetComponent<LineRenderer>();

        if (draw)
            CreatePoints();
    }

    private void Update()
    {
        if (Physics.CheckSphere(transform.position, xRadius, targetLayers))
        {
            Debug.Log("player detected");
        }
        else
        {
            Debug.Log("player NOT detected");
        }
    }

    void onm ouseDown()
    {
        
    }

    void onm ouseDrag()
    {
        xRadius = xRadius   0.01f;
        yRadius = yRadius   0.01f;
        CreatePoints();
    }

    public void CreatePoints()
    {
        line.enabled = true;
        line.widthMultiplier = width;
        line.useWorldSpace = false;
        line.widthMultiplier = width;
        line.positionCount = segments   1;

        float x;
        float y;

        var angle = 20f;
        var points = new Vector3[segments   1];

        for (int i = 0; i < segments   1; i  )
        {
            x = Mathf.Sin(Mathf.Deg2Rad * angle) * xRadius;
            y = Mathf.Cos(Mathf.Deg2Rad * angle) * yRadius;

            points[i] = new Vector3(x, height, y);

            angle  = (360f / segments);
        }
       
        line.SetPositions(points);
    }

#if UNITY_EDITOR
    private float prevXRadius, prevYRadius;
    private int prevSegments;
    private float prevWidth;
    private float prevHeight;

    private void OnValidate()
    {
        if (!line) line = GetComponent<LineRenderer>();
        if (!line) return;

        if (!draw)
        {
            line.enabled = false;
        }
        else
        {
            line.enabled = true;

            if (xRadius != prevXRadius || yRadius != prevYRadius || segments != prevSegments || width != prevWidth || height != prevHeight)
            {
                CreatePoints();

                prevXRadius = xRadius;
                prevYRadius = yRadius;
                prevSegments = segments;
                prevWidth = width;
                prevHeight = height;
            }

            if (controlBothXradiusYradius)
            {
                yRadius = xRadius;
            }
        }
    }
#endif
}

CodePudding user response:

OnMouseDrag is called every frame while the mouse is down.

You need to check the mouse position in onm ouseDrag.

Vector3 mousePos;

void onm ouseDown()
{
    mousePos = Input.mousePosition;
}

void onm ouseDrag()
{
    var newMousePos = Input.mousePosition;
    var delta = newMousePos - mousePos;
    if (delta.sqrMagnitude < 1)
        return;

    mousePos = newMousePos;

    xRadius = xRadius   0.01f;
    yRadius = yRadius   0.01f;
    CreatePoints();
}

CodePudding user response:

As Shingo said you have to take the mouse position into account!

However, in order to actually make this work I would make some additions.

Have in mind: The mouse position is in pixel space! So you will want to somehow convert it to world space coordinates.

I would do something like this

// The maximum distance in world units
[SerializeField] private float maxDistance = 1f;

private Vector3 initialMousePosition;

private Plane dragPlane;

[SerializeField] private Camera _mainCamera;
private Collider _collider;

private void Awake ()
{
    _collider = GetComponent<Collider>();
    if(!_mainCamera) _mainCamera = Camera.main;
}

void onm ouseDown()
{
    // Get the exact position where the mouse hits our collider
    // and also the ray direction, we will use it to get the current view plane
    // in order to map later mouse positions to the same range
    var ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
    // this should usually always be true since otherwise this onm ouseDown would not have been called
    if(_collider.Raycast(ray, out var hit))
    {
        initialMousePosition = hit.point;
        // Create a plane at the position of the object in XZ direction
        dragPlane = new Plane(Vector3.up, transform.position);
    }
}

void onm ouseDrag()
{
    // Similar as before but this time we use the Plane as target 
    var ray = _mainCamera.ScreenPointToRay(Input.mousePosition);
    if(dragPlane.Raycast(ray, out var distance))
    {
        var currentMousePosition = ray.GetPoint(distance);

        var distance = currentMousePosition - initialMousePosition;

        // Just to be sure erase any difference on Y 
        // (there shouldn't be any anyway since the plane is XZ only)
        distance.y = 0;
        // make sure the radius is combined maximum the maxDistance
        distance = Mathf.ClampMagnitude(distance, maxDistance);

        xRadius = distance.x;
        yRadius = distance.z;
        CreatePoints();
    }
}
  •  Tags:  
  • Related