Reputation: 3
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!
Upvotes: 0
Views: 1820
Reputation: 90659
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 thex
andy
components ofpoint
is a point inside this rectangle. IfallowInverse
is present andtrue
, thewidth
andheight
of theRect
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);
}
}
Upvotes: 2
Reputation: 481
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
Upvotes: 0