Forum rules - please read before posting.

Puzzle with multiple matching variables

I am trying to find the best solution for a panel puzzle in my game. There are variations of puzzles, but all connected to the same panels in the same room. Here's an illustration:

In one room the goal is to match the two panels. In another the goal is to reverse them. There are many more variations (such as flipping the combination vertically). To change the color of a button you press it. If it's red it turns blue, if it's blue it turns red and so on.

Since I have no coding background my first thought was to have a local variable associated to each button (ie blue = true, red = false) and check if you have the right combination at any variable change... It works, but it's tiresome, especially since I have so many variations of the puzzle. That's 18 local true/false variables!

Any ideas? :-)

Comments

  • edited February 2022

    Tbh I'd probably just go with 18 local boolean variables myself, but you could also just use two integers? For example, 111111111 could mean that all buttons are blue, and 0 would mean that all buttons are red. Then each digit could represent one button: if you want button #1 to change state, you can subtract or add 1; if you want button #2 change state, you can subtract or add 10; if you want button #3 to change state, you can subtract or add 100; and so on. Then you just need to check if both string variables are the same. The downside here is that unless you are careful, you might end up introducing bugs by adding 10 when the the second to last digit is already 1, etc, which would break the system.

    Imho, it's safer to create one actionlist comparing a set of 9 bools to the other set of 9 bools and call it a day.

  • Condensing the combined states of the buttons into a single value is a great way to compare one panel with another, but having a separate bools for each button also makes it easier to handle the updating of individual buttons when clicked.

    I wonder if a combination of both could be used.

    What you could try is to make each panel's Button a prefab, and then attach to that prefab a Variables component that contains a single Bool parameter to represent that Button's on/off state.

    The Panel's root object, that all these Buttons are parented to, could then have another Variables component that contains an Integer parameter to represent the combined state of all the Buttons.

    You could then rely on a single ActionList asset that is run whenever a Button Hotspot is clicked. This asset would include e.g. a Variable: Check / Set combination to flip a Bool variable, only it would use a Component Variable parameter can be used to assign the clicked Button's bool.

    When each Button is clicked, it would run this asset but assign its own Variables component as this parameter. This could be done by attaching the "Set Interaction Parameters" component. This too is "prefabbable", so making this change to the Button prefab would affect all at once.

    Even if you didn't rely on a separate Integer variable to represent the "combined" panel state, this'd help cut down drastically on the number of Actions to manage.

    If you wanted to go further and try @Rairun's suggestion, I'd suggest re-calculating the Panel's Integer variable from scratch. If you try to update it by adding/subtracting values, you'll need to make sure that its initial value matches that of the Buttons. This is best done through scripting:

    using UnityEngine;
    using AC;
    
    public class UpdatePanel : MonoBehaviour
    {
    
        public Variables panelVariables;
        public Variables[] buttonVariables;
    
        public void Recalculate ()
        {
            int panelValue = 0;
    
            for (int i = 0; i < buttonVariables.Length; i++)
            {
                bool buttonIsOn = buttonVariables[0].GetVariable (0).BooleanValue;
                if (buttonIsOn)
                {   
                    panelValue += Mathf.Pow (10, i);
                }
            }
    
            panelVariables.GetVariable (0).IntegerValue = panelValue;
        }
    
    }
    

    If this is attached to your Panel, you can assign all the Variables in its Inspector. To run the code above, use the Object: Send message Action to run the Panel object's Recalculate function.

    This too could be incorporated into the ActionList, with the Object to affect field set via GameObject parameter.

    This workflow should allow the whole Panel + Buttons to be made into a single prefab, with a single ActionList shared by all Panels.

    If you're new to this way of working in AC, this tutorial should help.

  • Thanks a lot guys, I got it working :smiley:

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.