Trouble with Physics2D.OverlapArea detection
I'm trying to generate a grid and place floor blocks along the bottom row using the addBlock method, but the condition isn't working properly. It is supposed to detect if there are any objects in the area the new block will be placed in. The problem is, unless the gridBlockWidth and gridBlockHeight variables are less than .9, it detects objects and will only place every other block.
The draw lines show the area being looked at. Green lines is the area looked at if a block is placed and yellow is the area if a block cannot be placed.
Can anyone help me?
P.S. I'm also having trouble with the new blocks that are instantiated coming up as null when I try to change their scale size (the newBlock.transform.localeScale). If anyone can help with this as well, I'd be grateful.
void createWorld()
{
gridWidth = Mathf.Clamp (gridWidth, 1, int.MaxValue);
gridHeight = Mathf.Clamp (gridHeight, 1, int.MaxValue);
levelGrid = new Vector2 [(gridWidth) * (gridHeight)];
int i = 0;
for (int col = 0; col < gridHeight; col++)
{
for (int row = 0; row < gridWidth; row++)
{
levelGrid[i] = new Vector2(row + transform.position.x, col + transform.position.y);
if (col == 0) //create a floor
{
//Debug.Log ("Adding " + floorBlock + " " + i);
addBlock (floorBlock, levelGrid[i]);
}
i++;
}
}
}
//Adds a block to the grid unless a block already occupies the space
public void addBlock(Object block, Vector2 vect)
{
float leftX = vect.x - gridBlockWidth / 2f + placementBuffer;
float botY = vect.y - gridBlockHeight / 2f + placementBuffer;
float rightX = vect.x + gridBlockWidth / 2f - placementBuffer;
float topY = vect.y + gridBlockHeight / 2f - placementBuffer;
Vector3 bottomLeft = new Vector3 (leftX,botY,0f);
Vector3 topRight = new Vector3 (rightX,topY,0f);
Vector3 topLeft = new Vector3 (leftX,topY,0f);
Vector3 bottomRight = new Vector3 (rightX,botY,0f);
float timeForDebug = 60f;
if (!Physics2D.OverlapArea (bottomLeft, topRight))
{
//Debug.Log ("Instantiating at " + vect);
GameObject newBlock = Instantiate(block, new Vector3 (vect.x, vect.y, 0f), Quaternion.identity) as GameObject;
//newBlock.transform.localScale = new Vector3(gridBlockWidth, gridBlockHeight, 0f);
Debug.DrawLine(bottomLeft, bottomRight, Color.green, timeForDebug);
Debug.DrawLine(bottomLeft, topLeft, Color.green, timeForDebug);
Debug.DrawLine(topLeft, topRight, Color.green, timeForDebug);
Debug.DrawLine(bottomRight, topRight, Color.green, timeForDebug);
}
else //FOR DEBUGGING; this shows the area being looked at
{
Debug.DrawLine(bottomLeft, bottomRight, Color.yellow, timeForDebug);
Debug.DrawLine(bottomLeft, topLeft, Color.yellow, timeForDebug);
Debug.DrawLine(topLeft, topRight, Color.yellow, timeForDebug);
Debug.DrawLine(bottomRight, topRight, Color.yellow, timeForDebug);
}
}
Answer by jgodfrey · Feb 21, 2016 at 03:14 PM
Are the blocks always laid out in a standard, rectangular grid configuration? If that's the case, why not simply track the blocks in in a 2D array? For example, if you had a 10x10 grid of blocks, you could:
Create a 10x10 array
Initialize all elements with a 0 (to indicate that no block exists at that position)
When you add a block at a given position, change the array element to 1 (to indicate a block exists at that position)
Then, it becomes easy to determine if a block exists at a given position. Simply look in the array at the row/column you're interested in. If the value of that element is "1", a block exists there.
Regarding the NullRef exception... I don't see anything wrong with your Instantiation code, assuming the "block" variable contains a valid reference. Does it?
Answer by Bebopjelli · Feb 22, 2016 at 03:07 AM
Still haven't fixed the detection issue. The idea was that, whether an object was created from a script or placed in the editor, objects could be detected and added or removed. I think adding pre-existing objects to an array would require the same condition anyway.
The strange thing is that a remove method with the same condition (only without the not) works fine.
Also, I've solved scaling issue. Thanks to jgodfrey, I found I had "block" be a BoxCollider2D instead of a GameObject, thanks!
Your answer
Follow this Question
Related Questions
Calculate distance and find nearest object 1 Answer
Ground Script explanation 1 Answer
How to make instantiated rigidbodies continue moving the in the same direction as destroyed object? 1 Answer
How do I Instantiate a Prefab to align with the closest object? 0 Answers
Physics2D.OverlapCircle works / Physics2D.OverlapCircleNonAlloc does not work 1 Answer