0
\$\begingroup\$

In my game, the player is presented with a plane containing obstacles (orange / blue) and regions of empty space (white).

The player moves their green cube around the empty space, which instantiates a trail of green cubes behind it, painting the path they've travelled.

I need to detect when the player has painted all of the empty space, so that they can proceed to the next level.

Initial state of the board:

Simple maze with a green square at one end of a channel

When the player has painted all of the empty space:

Same maze, with the channel fully covered in green

Currently I store my instantiated paint objects in a list.

But I don't know how to check that the objects in this list cover all of the empty space. How can I do that?

public float speed = 10f;
private RaycastHit hit;
public GameObject paintcube;
float maxdistance = 0.51f;
bool moves;



private void FixedUpdate()
{
    Debug.DrawRay(transform.position, transform.TransformDirection(Vector3.forward) * 3, Color.green);
    if (Physics.Raycast(transform.position,transform.TransformDirection(Vector3.forward), out hit, maxdistance/*,layerMask*/))
    {
         if (hit.collider.gameObject.tag == "myobstacle")
         {
             moves = false;                                                         
         }
         if(moves)
         {
             movepaint();
         }
     }
}   

public void movepaint()
{
     if (moves)
     {
         MyList.Add( Instantiate<GameObject>(paintcube, position, transform.rotation) );
     }
}       
\$\endgroup\$
1
\$\begingroup\$

You should discretize your space into a grid, and then determine how many of those squares are "covered" by something. I'd recommend making a GridArea class like so

public class GridArea : MonoBehaviour
{
    public float width; // Width in world space of the grid
    public float height; // Height in world space of the grid
    public int rows; // Number of rows in the grid
    public int columns; // Number of columns in the grid

    public float cellWidth { get { return width / columns; } }
    public float cellHeight { get { return height / rows; } }

    public Vector2 GetWorldPosition(int x, int y) {
        // Find the center of cell 0,0
        Vector2 bottomLeft = transform.position - new Vector2(width / 2, height / 2);
        bottomLeft += new Vector2(cellWidth, cellHeight);
        return bottomLeft + new Vector2(cellWidth * x, cellHeight * y);
    }
}

This class will break up your play area into small squares. To determine coverage you can go through each square and check if it is "covered". I would also advise adding an OnDrawGizmos function to help visualize the grid. So if you determine what % of the squares are covered, you get a rough estimate of what % of the map is covered. If you let your walls "cover" squares, then the only non covered is the play area. If player is above some threshold (say 95%) then they pass. The reason I chose the variables for the class that I did, is so you can keep the width/height of the play area fixed, and change the number of rows/columns to make it more accurate. The smaller the squares, the closer to the correct coverage you will measure. This is basically simple calculus. As the size of the squares approaches 0, your coverage measure will approach the actual value.

How you determine coverage is up to you. It could be as simple checking if the center of a grid cell is covered. You could check 4 points on the square and see if 2 or more are covered. There's lots of solutions you could try. Keep in mind performance throughout all of this. You could progressively measure coverage. Instead of always recomputing every square, start with the squares your level covers baked in. Then every time the player paints, update the squares that the paint affected, and recompute the %. Caching values will make things more performant and you can end up with a very effective solution.

Additionally I'd encourage that you don't instantiate squares as your painting method. You can look into decals, write a custom shader, paint to the texture, etc. Instantiation is heavy and should be avoided if you can for something like this that could end up with many many things being instantiated.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.