- Home /
Check if UI element is fully inside another UI element
Hey everyone, I'm doing a gridless inventory system, where you can freely move around items inside a container. The problem I'm facing is checking if an item (image) is completely inside the container (another image). How would I do this? I've tried getting each corner of the item image and then using the Contains function to check if the corners are inside the container, but for some reason that didn't work. Here's a snippet of the code that I've used to attempt to achieve this:
for (int c = 0; c < invContainers.Count; c++)
{
if (RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), Input.mousePosition))
{
Vector3[] corners = new Vector3[4];
obj.transform.GetChild(1).gameObject.GetComponent<RectTransform().GetLocalCorners(corners);
if (invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>().rect.Contains(corners[0])
&& invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>().rect.Contains(corners[1])
&& invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>().rect.Contains(corners[2])
&& invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>().rect.Contains(corners[3]))
{
Debug.Log("Can drop the item in ID " + c);
obj.transform.SetParent(invContainers[c].obj.transform.GetChild(2));
obj.GetComponent<RectTransform>().localScale = Vector2.one;
obj.GetComponent<RectTransform>().position = tempCoords;
}
else
{
Debug.Log("Can't drop here");
}
}
}
Using this code, I seem to pass through this check even if only 1 corner is inside the container (it's almost like it ignores the corner check). If anyone has any suggestions or a solution, please share them with me, I will greatly appreciate them. Thank you in advance.
EDIT: Fixed by using RectangleContainsScreenPoint instead of rect.Contains. Here's the working code below:
for (int c = 0; c < invContainers.Count; c++)
{
if (RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), Input.mousePosition))
{
Vector3[] corners = new Vector3[4];
obj.transform.GetChild(1).gameObject.GetComponent<RectTransform>().GetWorldCorners(corners);
if (RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), corners[0])
&& RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), corners[1])
&& RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), corners[2])
&& RectTransformUtility.RectangleContainsScreenPoint(invContainers[c].obj.transform.GetChild(2).gameObject.GetComponent<RectTransform>(), corners[3]))
{
Debug.Log("Can drop the item in ID " + c);
obj.transform.SetParent(invContainers[c].obj.transform.GetChild(2));
invContainers[c].items.Add(obj.GetComponent<InventoryItem>().item);
obj.GetComponent<RectTransform>().localScale = Vector2.one;
obj.GetComponent<RectTransform>().position = tempCoords;
obj.GetComponent<InventoryItem>().containerID = c;
calculateWeight();
UpdateContainers();
}
else
{
Debug.Log("Can't drop here");
obj.GetComponent<InventoryItem>().ResetPos();
}
}
}
I'm not sure, but there can be a few things to check.
First, if You are checking against proper camera here: RectangleContainsScreenPoint
Second, if Vector3[] corners
has proper Z depth for each of them. Third, if proper objects are taken from GetChild
Fourth, debug, Your corners of object and containrer. Display them using Debug.Log
or in some other, nice way.
Personally I would use BoxColliders
for walls of the container, and volume of objects, and check collisions of them. Also do something like: if object collides with container wall, move it to closest, empty space of container
.
Please, provide information what have You done to resolve Your problem. Someone, will probably help with further problems about this topic.
If my previous comment helped enough, please inform, I'll turn it into an answer.
It's sad to see many questions left for death. :(
Thanks for your help, I already fixed it by using RectangleContainsScreenPoint
ins$$anonymous$$d of rect.Contains
Answer by dbdenny · Mar 24, 2020 at 02:19 AM
public static bool RectContainsAnother (RectTransform rct, RectTransform another)
{
var r = rct.GetWorldRect();
var a = another.GetWorldRect();
return r.xMin <= a.xMin && r.yMin <= a.yMin && r.xMax >= a.xMax && r.yMax >= a.yMax;
}
Is GetWorldRect a 3rd party extension or within unity docs?
Your answer
Follow this Question
Related Questions
Matching the size of UI elements with that of world objects 0 Answers
Display loaded UI Image in Container with native size 0 Answers
How to move UI Image under the other UI elements? 3 Answers
Saving image in a variable purely through code? 1 Answer
How to copy one Rect Transform data to other Rect Transform 2 Answers