简体   繁体   中英

Checking if an Vector2 is inside of the area of two other vector 2's

this problem is quite hard to describe on my part so I will try my best at showing my problem and showing how I did it and if someone can find a better solution than i did.

    public bool selectcheck(Vector3 firstpos, Vector3 secondpos)
    {
        if (firstpos.x < gameObject.transform.position.x && firstpos.y < gameObject.transform.position.y && secondpos.x > gameObject.transform.position.x &&secondpos.y > gameObject.transform.position.y)
        {
            selected = true;
        }
        else if (firstpos.x > gameObject.transform.position.x && firstpos.y < gameObject.transform.position.y && secondpos.x < gameObject.transform.position.x && secondpos.y > gameObject.transform.position.y)
        {
            selected = true;
        }
        else if (firstpos.x < gameObject.transform.position.x && firstpos.y > gameObject.transform.position.y && secondpos.x > gameObject.transform.position.x && secondpos.y < gameObject.transform.position.y)
        {
            selected = true;
        }
        else if (firstpos.x > gameObject.transform.position.x && firstpos.y > gameObject.transform.position.y && secondpos.x < gameObject.transform.position.x && secondpos.y < gameObject.transform.position.y)
        {
            selected = true;
        } // this checks if the positions sent is inside the unit's position
        else
        {
            selected = false;
        }
        return selected;
    } // Selected is outside as a public bool and that is used to allow the unit to respond to the player's commands and this only tells the master script that sends this to the unit that it wants it checked out and the info sent back

I know that the code looks horrendous but I was searching everywhere for something that uses only 2 points in space to check IF the unit is inside of the specified vector2

btw the code works but I really think I can make it better in some way, shape or form because the game will have about 100 units, and having that many else if's at one time when you select units, is going to be very bad indeed.

thanks in beforehand!

I guess you are having all those chained IFs because firstpos and secondpos are not ordered ( firstpos.x always < secondpos.x and firstpos.y always < secondpos.y )

So you could simplify a little your algorithm by doing something like this:

    public bool selectcheck(Vector3 firstpos, Vector3 secondpos)
    {
        var loPoint = firstpos;
        var hiPoint = secondpos;

        // swap x if needed
        if (loPoint.x > hiPoint.x)
        {
            var tempX = loPoint.x;
            loPoint.x = hiPoint.x;
            hiPoint.x = tempX;
        }

        // swap y if needed
        if (loPoint.y > hiPoint.y)
        {
            var tempY = loPoint.y;
            loPoint.y = hiPoint.y;
            hiPoint.y = tempY;
        }

        // just check if point is inside
        return gameObject.transform.position.x > loPoint.x && gameObject.transform.position.x < hiPoint.x
            && gameObject.transform.position.y > loPoint.y && gameObject.transform.position.y < hiPoint.y;
    }

Now, if you can find a way to ensure firstpos is always less than secondpos , you can take the swap steps out and the function would be faster

Actually you could simply create the according Rect that is between your two points using Rect.MinMaxRect and then simply check via Contains

Returns true if the x and y components of point is a point inside this rectangle. If allowInverse is present and true , the width and height of the Rect are allowed to take negative values (ie, the min value is greater than the max), and the test will still work.

public bool selectcheck(Vector2 firstpos, Vector2 secondpos)
{
    var rect = Rect.MinMaxRect(firstpos.x, firstpos.y, secondpos.x, secondpos.y);
    return rect.Contains(transform.position, true);
}

Just as a sidenote: If you where about to do the same but for 3D positions just replace the Rect by a Bounds and do

public bool selectcheck(Vector3 firstpos, Vector3 secondpos)
{
    var bounds = new Bounds(firstpos, Vector3.zero);
    bounds.Encapsulate(secondpos);
    return bounds.Contains(transform.position, true);
}

Just as a little example

Each of the cubes has the following script attached and first and second are the to spheres I am moving around;)

public class Example : MonoBehaviour
{
    public Transform first;
    public Transform second;

    private Material _material;

    private void Start()
    {
        _material = GetComponent<MeshRenderer>().material;
    }

    private void Update()
    {
        UpdateSelectColor();
    }

    private void UpdateSelectColor()
    {
        // set the color to green if selected or red if not
        _material.color = selectcheck(first.position, second.position) ? Color.green : Color.red;
    }

    public bool selectcheck(Vector2 firstpos, Vector2 secondpos)
    {
        var rect = Rect.MinMaxRect(firstpos.x, firstpos.y, secondpos.x, secondpos.y);

        return rect.Contains(transform.position, true);
    }

    // just for visualizing the calculated rect 
    private void OnDrawGizmos()
    {
        var rect = Rect.MinMaxRect(first.position.x, first.position.y, second.position.x, second.position.y);

        Gizmos.color = Color.cyan;
        Gizmos.DrawWireCube(rect.center, rect.size);
    }
}

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM