Building Your First Brain Test Puzzle Logic in Unity (With Full Code)


What's Next? (Moving towards a real puzzle)


In the last tutorial, we learned how to set up Unity, create a simple 2D scene, and detect taps on objects — a huge first step toward building your Brain Test–style puzzle game. 🎯

Now it’s time to make those taps actually mean something. In this chapter, we’ll evolve our prototype into a real puzzle by introducing correct and incorrect answers, a GameManager to control game flow, and clear player feedback like “✅ Correct!” and “❌ Try Again!”.

By the end of this guide, you’ll have a functional mini puzzle system that reacts to the player’s actions — rewarding correct answers and resetting after mistakes — just like the popular mobile brain teaser games. 🧩

If you’ve followed the previous step, your project is ready. Let’s dive in and bring your puzzle logic to life. 🚀Now that we have basic tap detection working, let's evolve this into a proper puzzle. Learn how to implement puzzle logic in Unity using C#. This step-by-step guide covers tap detection, GameManager setup, feedback messages, and resetting your first Brain Test–style puzzle.

Goal for this next step:

  1. Introduce the concept of "correct" and "incorrect" objects.

  2. Implement a GameManager to track the puzzle's state.

  3. Display "Correct!" or "Try Again!" feedback.

  4. Reset the puzzle for another attempt.

Let's modify our TapInteractable script and introduce a GameManager script.


Step 1: Modify 

We need a way to tell our TapInteractable objects if they are the correct solution for the current puzzle.

  1. Open  again in your code editor.

  2. Add a variable to the class to mark if it's the correct answer.

  3. Modify the  to inform the GameManager of the tap and whether it was correct.

    Replace the entire content of your TapInteractable.cs script with this updated code:

    C#
    using UnityEngine;
    using UnityEngine.UI;
    using UnityEngine.EventSystems;
    
    public class TapInteractable : MonoBehaviour, IPointerClickHandler
    {
        [SerializeField] private bool isCorrectAnswer = false; // NEW: Set this in the Inspector
    
        // Store the initial color to reset it later
        private Color initialColor;
        private Image imageComponent;
    
        private void Awake()
        {
            imageComponent = GetComponent<Image>();
            if (imageComponent != null)
            {
                initialColor = imageComponent.color; // Save original color
            }
        }
    
        public void OnPointerClick(PointerEventData eventData)
        {
            Debug.Log(gameObject.name + " was tapped!");
    
            // Inform the GameManager about the tap
            if (GameManager.Instance != null)
            {
                GameManager.Instance.HandleTapInteraction(this, isCorrectAnswer);
            }
            else
            {
                Debug.LogError("GameManager not found! Make sure it's in the scene and has an instance.");
            }
        }
    
        // NEW: Public method to reset the object's visual state
        public void ResetVisuals()
        {
            if (imageComponent != null)
            {
                imageComponent.color = initialColor; // Reset to original color
            }
        }
    
        // NEW: Public method to highlight correct/incorrect
        public void SetHighlightColor(Color color)
        {
            if (imageComponent != null)
            {
                imageComponent.color = color;
            }
        }
    }
  4. Save the script.


Step 2: Create the 

We need a single, central script to manage the game's state, check puzzle answers, and provide feedback. A common way to do this is using the Singleton Pattern, which ensures there's only one instance of GameManager available globally.

  1. Create 

    • In the Project window, go to your _Scripts folder.

    • Right-click Create > C# Script.

    • Name it GameManager.

  2. Open  in your code editor.

  3. Paste the Code:

    • Delete all default code.

    • Paste this code into GameManager.cs:

    C#
    using UnityEngine;
    using TMPro; // Needed for TextMeshPro UI elements
    using System.Collections; // Needed for Coroutines (for delays)
    
    public class GameManager : MonoBehaviour
    {
        // Singleton pattern: allows other scripts to easily access this manager
        public static GameManager Instance { get; private set; }
    
        [Header("UI References")]
        [SerializeField] private TextMeshProUGUI feedbackText; // Drag your feedback text here
        [SerializeField] private TapInteractable[] interactableObjects; // Drag all tap-able objects here
    
        [Header("Game Settings")]
        [SerializeField] private float feedbackDisplayDuration = 2f; // How long "Correct!" / "Try Again!" stays on screen
    
        private void Awake()
        {
            // Enforce singleton pattern
            if (Instance != null && Instance != this)
            {
                Destroy(gameObject);
                return;
            }
            Instance = this;
    
            // Initialize UI
            if (feedbackText != null)
            {
                feedbackText.text = ""; // Clear feedback text on start
                feedbackText.gameObject.SetActive(false); // Hide it
            }
            else
            {
                Debug.LogError("Feedback Text is not assigned in GameManager!");
            }
        }
    
        // This method is called by TapInteractable when an object is tapped
        public void HandleTapInteraction(TapInteractable tappedObject, bool isCorrect)
        {
            // Prevent multiple taps while feedback is showing
            if (feedbackText.gameObject.activeSelf) return;
    
            if (isCorrect)
            {
                ShowFeedback("CORRECT!", Color.green);
                // In a real game, you would now load the next level or perform other win actions
                Debug.Log("Puzzle Solved! Moving to next level (not implemented yet).");
            }
            else
            {
                ShowFeedback("TRY AGAIN!", Color.red);
                tappedObject.SetHighlightColor(Color.red); // Highlight the incorrect object
                StartCoroutine(ResetPuzzleAfterDelay()); // Reset after a short delay
            }
        }
    
        private void ShowFeedback(string message, Color color)
        {
            if (feedbackText != null)
            {
                feedbackText.gameObject.SetActive(true);
                feedbackText.text = message;
                feedbackText.color = color;
                // Optionally hide after a delay if it's a "Correct!" message as well
                if (message == "CORRECT!")
                {
                    StartCoroutine(HideFeedbackAfterDelay(true));
                }
            }
        }
    
        private IEnumerator HideFeedbackAfterDelay(bool loadNextLevel)
        {
            yield return new WaitForSeconds(feedbackDisplayDuration);
            if (feedbackText != null)
            {
                feedbackText.gameObject.SetActive(false);
            }
    
            if (loadNextLevel)
            {
                // TODO: Implement actual level loading here
                Debug.Log("Placeholder: Next level would load now.");
                ResetAllInteractables(); // For testing, just reset
            }
        }
    
        private IEnumerator ResetPuzzleAfterDelay()
        {
            yield return new WaitForSeconds(feedbackDisplayDuration);
            if (feedbackText != null)
            {
                feedbackText.gameObject.SetActive(false);
            }
            ResetAllInteractables();
        }
    
        private void ResetAllInteractables()
        {
            foreach (TapInteractable obj in interactableObjects)
            {
                if (obj != null)
                {
                    obj.ResetVisuals(); // Reset the color of all interactable objects
                }
            }
        }
    }
  4. Save the script.


Step 3: Configure Unity Objects with the New Scripts

Now we need to connect everything in the Unity Editor.

  1. Attach 

    • In the Hierarchy, select the _GameManager GameObject you created earlier.

    • In the Inspector, click Add Component.

    • Search for GameManager and add it.

  2. Create a Feedback Text UI:

    • In the Hierarchy, right-click on your Canvas.

    • Select UI > Text - TextMeshPro.

    • Rename it FeedbackText.

    • Select FeedbackText. In the Inspector:

      • Rect Transform > Pos X0

      • Rect Transform > Pos Y0

      • Rect Transform > Width900

      • Rect Transform > Height300

      • TextMeshPro - Text > Text Input: Clear any default text.

      • TextMeshPro - Text > Font Size100 (make it big!)

      • TextMeshPro - Text > AlignCenter (both horizontal and vertical).

      • TextMeshPro - Text > Color: Set to White initially.

      • Important: Uncheck the checkbox next to the FeedbackText GameObject's name in the Hierarchy. This will hide it by default.

  3. Connect UI to 

    • Select the _GameManager GameObject in the Hierarchy.

    • In the Inspector, under the GameManager (Script) component, you'll see new fields:

      • For Feedback Text: Drag your FeedbackText (from the Hierarchy) into this slot.

      • For Interactable Objects:

        • Set the Size to 2 (since we have 2 objects for now).

        • Drag SquareObject (from the Hierarchy) into Element 0.

        • Drag CircleObject (from the Hierarchy) into Element 1.

  4. Configure 

    • Select SquareObject in the Hierarchy.

    • In the Inspector, find its TapInteractable (Script) component.

    • Crucially, decide which one is the correct answer for your puzzle: "What object is out of place?" Let's say the Circle is out of place among squares (though we only have one square for now). So, the Circle should be the correct answer.

    • For SquareObject, ensure Is Correct Answer is UNCHECKED.

    • Select CircleObject in the Hierarchy.

    • For CircleObject, ensure Is Correct Answer is CHECKED.

  5. Save Your Scene: File > Save (or Ctrl+S / Cmd+S).


Step 4: Test Your First Puzzle!

  1. Run the Game: Click the Play button.

  2. Test Incorrect Tap:

    • Tap the red square.

    • You should see "TRY AGAIN!" in red in the middle of the screen.

    • The square should momentarily turn red (highlighting it was wrong).

    • After a short delay, "TRY AGAIN!" should disappear, and the square should revert to its original red color.

  3. Test Correct Tap:

    • Tap the blue circle.

    • You should see "CORRECT!" in green in the middle of the screen.

    • After a short delay, "CORRECT!" should disappear, and the circle should revert to its original blue color.

    • In the Console, you'll see a message "Puzzle Solved! Moving to next level (not implemented yet)."


You now have a fully functional, albeit simple, "Brain Test" style puzzle!

This setup provides:

  • A central GameManager for overall control.

  • Interactive elements that know if they're correct.

  • Visual and textual feedback to the player.

  • Automatic resetting of the puzzle after an incorrect guess.

This is a fantastic foundation to build upon. Next, we can think about adding more complex interactions like drag-and-drop, or how to manage multiple levels.

How did that go? Did you manage to get the puzzle working as described?

Conclusion:

Congratulations — your puzzle logic is now alive! 🥳

You’ve built a system that understands what’s right and wrong, provides instant feedback, and resets itself for the next attempt. This may seem simple, but it’s the core mechanic behind every brain teaser, riddle, and logic puzzle game.

From here, your possibilities expand fast. You can now:

  • 🎨 Add more objects and make complex puzzles.

  • 🔁 Load multiple levels or randomize challenges.

  • 🧩 Introduce drag-and-drop, hidden clues, or timed puzzles.

  • 📱 Start testing on mobile for touch interaction and polish.

In the next part, we’ll explore how to create a level system so you can move from one puzzle to the next — just like in Brain Test, Tricky Puzzle, or Who’s Lying?.

Keep experimenting, keep solving — and remember, every “Try Again!” brings you closer to “Correct!”. 💡


Comments

Popular posts from this blog

Step-by-Step Guide on How to Create a GDD (Game Design Document)

How to Create a Brain Test–Style Puzzle Game in Unity (Step-by-Step Guide for Beginners)

Master Drag & Drop in Unity: Build Engaging Puzzle Games (Step-by-Step Tutorial)