-3

I want to create a safety check in a game for children so only the parents can access a specific area. The script of checking the input is done and working. What I am trying to create is a feedback to see what number is already clicked. Parents must enter a certain sequence of numbers. For example they have to click "Five" and when they do I want to text to change to be italic.

If a wrong number is entered, you have to start the whole entry from the beginning (already scripted). That means if they click a wrong number the text have to go from italic to normal.

Here you can see the way it should look. I am using Text.MeshPro for the texts

It would be super awesome if someone could help me :)

I really have no idea what I am doing. For creating the general safety check, I used the following script:

using DefaultNamespace.Logging;
using DefaultNamespace.ParentSecurity;
using DefaultNamespace.SceneManager;
using UnityEngine;

public class ParentSecureController : MonoBehaviour
{
    public SceneManager sceneManager;
    public SceneNames targetSceneName;

    private readonly int[] code = new int[5]
    {
        5, 3, 4, 1, 2
    };

    private int index;

    private void Start()
    {
        foreach (var numberItem in GetComponentsInChildren<NumberItem>()) numberItem.SetParentSecureController(this);
    }
    // Update is called once per frame

    public void CheckInput(int number)
    {
        CustomLogger.Log("In CheckInput,  code:" + code);
        CustomLogger.Log("In CheckInput,  index:" + index);

        CustomLogger.Log("In CheckInput, nbr:" + number);
        if (number == 0) return;
        if (index >= 4)
            sceneManager.LoadScene(targetSceneName);
        else if (number == code[index])
            index++;
        else
            index = 0;
    }
}

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • 1
    and what exactly is your question? What does your code **actually** do and what is it **supposed** to do? – MakePeaceGreatAgain Jul 24 '23 at 10:48
  • btw - by that you confirm that someone can read / recognize number names - it does in no way ensure that someone is an adult ;) Additionally children learn darn quick and if they ever manage to see what their parents click in order they will simply copy the movement ;) Add some randomness at least ;) – derHugo Jul 24 '23 at 10:51
  • Hi, my question is: How do I create the part where the text is changing to italic/ normal based on my input? – Alenasteffx Jul 24 '23 at 10:51
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Jul 24 '23 at 17:09

1 Answers1

0

In general you can simply change that via

someTmpText.fontStyle = FontStyles.Italic;

Then as said I would rather insert some randomness instead of a hard-coded code.

First of all I would have an enum for simply having names and values together:

public enum Numbers
{
    Zero,
    One,
    Two,
    Three,
    Four,
    Five,
    Six,
    Seven,
    Eight,
    Nine
}

and then there are two different UI items

  • Your number buttons
  • The indicator texts for which buttons to press

I would have

  • a dedicated component for each
  • a prefab for each

The component attached to the button prefab

public class NumberItem : MonoBehaviour
{
    [SerializeField] private Button button;

    private Action<Numbers> clickCallback;
    private Numbers value;

    private void Awake()
    {
        button.onClick.AddListener(OnClick);
    }

    public void Initilaize(Numbers value, Action<Numbers> clickCallback)
    {
        this.value = value;
        this.clickCallback = clickCallback;
    }

    private void OnClick()
    {
        clickCallback?.Invoke(value);
    }
}

and for the UI display text e.g.

public class NumberIndicator : MonoBehaviour
{
    [SerializeField] private TMP_Text text;
    
    public void Initialize(Numbers number)
    {
        text.text = number.ToString();
    }

    public void SetPassed()
    {
        text.fontStyle = FontStyles.Strikethrough;
    }
}

and then finally as mentioned do some randomization of the numbers and do

    // get an array of all available numbers once
    private static readonly Numbers[] _allNumbers = (Numbers[])Enum.GetValues(typeof(Numbers));

    public SceneManager sceneManager;
    public SceneNames targetSceneName;

    // The two prefabs to be spawned
    [SerializeField] private NumberItem _NumberButtonPrefab;
    [SerializeField] private NumberIndicator _NumberIndicatorPrefab;
    
    // The two parents that those prefabs will be spawned as child as
    [SerializeField] private Transform _NumberButtonsContainer;
    [SerializeField] private Transform _NumberIndicatorsContainer;

    // configure the length of the code
    [SerializeField] private int _codeLength = 5;
    
    // will hold the current code sequence
    private Numbers[] _currentSequence;
    // index like you had already
    private int _index;

    private readonly List<NumberIndicator> _NumberIndicatorInstances = new List<NumberIndicator>();
    
    private void Start()
    {
        InitSequence();
    }

    private void InitSequence()
    {
        // create a new random sequence without repeating from available numbers of given _codeLength
        _currentSequence = _allNumbers.OrderBy(_ => Random.value).Take(_codeLength).ToArray();
        // reset input index
        _index = 0;

        // Destroy all number indicators and buttons
        // you could use pooling of course but this is just easier and impact should be neglectable
        foreach(var indicator in _NumberIndicatorInstances)
        {
            Destroy(indicator.gameObject);
        } 
        _NumberIndicatorInstances.Clear();
        foreach (Transform child in _NumberButtonsContainer)
        {
            Destroy(child.gameObject);
        }
        
        // spawn indicators in order and set display name
        foreach (var number in _currentSequence)
        {
            var numberIndicator = Instantiate(_NumberIndicatorPrefab, _NumberIndicatorsContainer);
            numberIndicator.Initialize(number); 
            _NumberIndicatorInstances.Add(numberIndicator);
        }
        
        // spawn buttons in again shuffled order and set value and callback
        foreach (var number in _currentSequence.OrderBy(n => Random.value))
        {
            var numberItem = Instantiate(_NumberButtonPrefab, _NumberButtonsContainer);
            numberItem.Initilaize(number, HandleClick);
        }
    }

    // handle the button clicks as before
    private void HandleClick(Numbers value)
    {
        // unexpected input => reset and start new sequence
        if (_currentSequence[_index] != value || _index >= _currentSequence.Length)
        {
            Debug.LogError("Wrong input!");
            InitSequence();
            return;
        }

        // otherwise mark indicator as passed and go to next
        _NumberIndicatorInstances[index].SetPassed();
        
        // prepare for next input
        _index++;

        // if reaching last index go to scene
        if (_index == _currentSequence.Length)
        {
            sceneManager.LoadScene(targetSceneName);
        }
    }
}
derHugo
  • 83,094
  • 9
  • 75
  • 115