Monday, March 25, 2019

The Witness Puzzle Mechanic Study

The Witness's puzzle mechanic recreated in unity.


I was playing the witness and couldn't help myself but to recreate the puzzles in unity.

I first started by creating a world space canvas with a cursor on it. I simply tied the movement of the cursor to the mouse x and y. I did not translate from screen space to world space as this would create undesired effects.

After i had the cursor moving around, i created button on the ui canvas that activated initialized the puzzle. This is the white circle on the puzzle, and works just like the game. Once the puzzle is clicked on, i turn off the player movement, and add a border to the screen. The player can then reset the puzzle by clicking the button again.

I then needed to constrict the cursor to "Lines" of the puzzle. I did this by creating an array of rectTransforms and getting their world Corners. I then turn that into a rect and grab the world corners of the cursor collider (where we are trying to move the cursor). Its then as simple as checking if the rects overlap. Note that i do this twice because i check the delta x and then the delta y of the cursor.

Now that i have a cursor on rails, i need to connect using a line. That line is created of spawned image prefabs. You can see the line parts being spawned in and destroyed in the gif above.

The last part was the most difficult. I needed to create the "Puzzle Elements". If you have played the game, you'll know that each symbol represents a requirement for the puzzle. Take the black hexagons, you need to move your line over every black hexagon without missing any.

This can be done with an two dimensional array. Each puzzle element has a vector 2 variable which represents its position in the array. When we create the array, false will represent an empty spot, and true will represent somewhere where the line is. When the puzzle is complete, we simply need to give the array to each puzzle element and (in this case) we need to check and see if that elements spot is marked as true (the line overlaps)

The only issue is creating that array. I did this by marking each corner with a vector 2. This represents where in the array that corner should represent. The main problem with doing it this way is that you can have unforeseen issues if corners are marked improperly. Each corner is marked in the above picture.

The only other interesting part is the other puzzle elements. For the black and white squares, i use a fill algorithm to check every reachable spot for an opposingly colored square. If another square of opposing color is found, the element fails.

I do the same thing with the suns, but just count the number of found suns and ensure it is only one other sun.


  1. Hi

    I'm a University student and I'm very interested in making "The Witness" puzzles in Unity and I find this blog.

    However, I find that the unity package is no longer available through the link you provided.

    Could you please upload the unity package to Github or somewhere else? That would be so apprciated.

    Best Wishes

  2. Hello! I need to know how to do this, please! My Email is: