Comment on page


Adding New Puzzles

You can create two types of puzzles: complex puzzles that change the camera and derive from PuzzleBase, or simple puzzles that only disable interaction and derive from PuzzleBaseSimple.
  1. 1.
    Write a new script and derive it from PuzzleBase or PuzzleBaseSimple based on your specific requirements.
Complex Puzzle
Simple Puzzle
  1. 2.
    When deriving from Puzzle Base, the script inspector may look messy. To tidy it up, you can write a basic editor script and place it in the Editor folder. For instance, you can name the script TestPuzzleEditor.
using UHFPS.Runtime;
// derive from PuzzleBase or PuzzleBaseSimple
public class TestPuzzle : PuzzleBase
public string TestString;
public float TestFloat;
using UnityEngine;
using UnityEditor;
using ThunderWire.Editors;
namespace UHFPS.Editors
// derive from PuzzleEditor<T> or PuzzleSimpleEditor<T>
public class TestPuzzleEditor : PuzzleEditor<TestPuzzle>
public override void OnEnable()
// when overriding OnEnable(), do not remove the base.OnEnable()
public override void OnInspectorGUI()
EditorDrawing.DrawInspectorHeader(new GUIContent("Test Puzzle"), Target);
base.OnInspectorGUI(); // this will draw settings dropdown
Test Puzzle script with Custom Editor
To draw script properties, you can follow the same process as when creating an editor script for the Player Item script.
  1. 3.
    Create a new Cinemachine Virtual Camera by selecting GameObject -> Cinemachine -> Virtual Camera and add it to the puzzle object. Then assign it to the Puzzle Camera field in the Puzzle Base Settings.
  1. 4.
    Within the Cinemachine Virtual Camera component, set Body to Do nothing and Aim to Do nothing. Then, disable the object.
Be sure to disable the Virtual Camera object, as Cinemachine will automatically switch to the active virtual camera object.
PuzzleBase or PuzzleBaseSimple contain the base functions and properties for puzzles, so it's worth examining what's included in these classes to ensure proper usage. The functions are commented, so it should be easy to determine what you can use in your script. Remember to include the base. call when overriding the methods.
  1. 5.
    Assign the controls for your puzzle that will be displayed on the puzzle screen to the Controls Format field. The controls should follow this format: [action] Action Title.
To create new controls, you can refer to the instructions on the Localization page or select the magnifying glass icon and assign existing controls.
After completing the previous steps, when you interact with the object, the camera should switch to a puzzle camera with a pointer. The puzzle pointer uses the IInteractStart interface to interact with the puzzle object. To enable puzzle colliders, simply specify Colliders Enable or Colliders Disable. So, when you interact with a puzzle, you should enable puzzle colliders so that you can only interact with puzzle objects when you are on the puzzle screen.

Lockpick Puzzle

  1. 1.
    To use lockpick puzzle, add the Lockpick Interact component to the puzzle object.
  2. 2.
    Assign a Lockpick Model that includes the Lockpick Component script. You can choose from Lockpick_Chest or Lockpick_Door.
If you want to display a lockpick screen when interacting with a locked door, simply enable the Is Dynamic Unlock Component toggle. This will disable the On Unlock event and instead it will unlock the dynamic door. Then simply assign the Unlock Script with Lockpick Interact.
  1. 3.
    Select the Bobby Pin Item, by clicking the circular button located to the right of the Item Guid field.
Now you should be able to interact with the puzzle object that displays the lockpicking screen.