简体   繁体   中英

How can I limit the numbers typing input length?

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

public class SecurityKeypadKeys : MonoBehaviour
{
    [SerializeField] private int _number;

    public event Action<int> onKeyPressed;

    private void Awake()
    {
        name = $"Key {_number}";
    }

    private void OnMouseDown()
    {
        onKeyPressed?.Invoke(_number);
    }
}

And this script get the pressed numbers and show them in a text ui :

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SecurityKeypadSystem : MonoBehaviour
{
    [Header("References")]
    // rather let this class control the display text
    [SerializeField] private TextMesh _text;

    [Header("Settings")]
    // also rather let this class control the length of a code
    [SerializeField] private int _codeLength = 8;

    [Header("Debugging")]
    [SerializeField] private GameObject[] _keyPadNumbers;
    [SerializeField] private List<int> _code = new List<int>();

    // This will be invoked once the code length has reached the target length
    public event Action<int> OnCodeComplete;

    // Start is called before the first frame update
    private void Start()
    {
        var KeyPadNumbersParent = GameObject.FindGameObjectWithTag("KeypadParent").GetComponentsInChildren<Transform>(true);
        foreach (Transform child in KeyPadNumbersParent)
        {
            if (child.gameObject.GetComponent<SecurityKeypadKeys>() != null)
            {
                var securityKeypadKeys = child.gameObject.GetComponent<SecurityKeypadKeys>();
                securityKeypadKeys.onKeyPressed -= HandleKeyPressed;
                securityKeypadKeys.onKeyPressed += HandleKeyPressed;
            }
        }
    }

    private void OnDestroy()
    {
        // just for completeness you should always remove callbacks as soon as they are not needed anymore
        // in order to avoid any exceptions
        foreach (var keyPadNumber in _keyPadNumbers)
        {
            var securityKeypadKeys = keyPadNumber.GetComponent<SecurityKeypadKeys>();
            securityKeypadKeys.onKeyPressed -= HandleKeyPressed;
        }
    }

    // this is called when a keypad key was pressed
    private void HandleKeyPressed(int value)
    {
        // add the value to the list
        _code.Add(value);

        if (_code.Count != _codeLength)
        {
            _text.text += value.ToString();
        }

        // Check if the code has reached the target length
        // if yes prcoess further
        if (_code.Count == _codeLength)
        {
            // if it reached the length combine all numbers into one int
            var exponent = _code.Count - 1;
            float finalCode = 0;
            foreach (var digit in _code)
            {
                finalCode += digit * Mathf.Pow(10, exponent);
                exponent--;
            }

            // invoke the callback event
            OnCodeComplete?.Invoke((int)finalCode);

            // and reset the code
            StartCoroutine(ResetCodeTime());
        }
    }

    IEnumerator ResetCodeTime()
    {
        yield return new WaitForSeconds(1f);

        ResetCode();
    }

    // Maybe you later want an option to clear the code field from the outside as well
    public void ResetCode()
    {
        _code.Clear();
        _text.text = "";
    }

    // also clear the input if this gets disabled
    private void OnDisable()
    {
        ResetCode();
    }
}

In this case the code length is 8 :

private int _codeLength = 8;

And in the HandleKeyPressed I'm starting a Coroutine for a second to display also the last typed number on the text ui.

The problem is if the player will type fast enough not so fast but enough it will show more 3 digits before the Coroutine will reset it. I tried to avoid this by adding a check :

if (_code.Count != _codeLength)
            {
                _text.text += value.ToString();
            }

but it's not working. If I type fast enough it will display more 3-4 digits on the text ui before reset. I want that in any case the player will be able to type in only 8 digits or the length of the code if it's 8 or 10 or 2 and not more then that.

You should be able to solve this by using the Range attribute, as documented here .

Directly from the example, modifying it according to your needs:

    // This int will be shown as a slider in the Inspector
    [SerializeField]
    [Range(0, 99999999)]
    private int _number;

You can have a bool that tells you if the code is in the process of resetting:

bool isResetting;
IEnumerator ResetCodeTime()
{
    isResetting = true;
    yield return new WaitForSeconds(1f);
    ResetCode();
    isResetting = false;
}

And then you can check it in HandleKeyPressed :

private void HandleKeyPressed(int value)
{
    if(isResetting){
        //cannot enter more digits, code is resetting. 
        return;
    }
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM