Using Decimal number validation for input fields forces user to type using period as separator instead of CurrentCulture separator. In creates some problems, for ex. this sample won’t work for all users:float.TryParse(inputField, var out value);
Why? By default TryParse uses CurrentCulture. If user culture uses comma as separator then he is forced to use period what breaks that code.
I actually also like to have both options: comma and dot. UnityEditor also allows both when inserting a floating point number in the inspector (at least if the current culture is German). This is very useful since the num-pad separator key is a comma in German.
However, It is problematic as soon as you support thousands-separators: while the invariant separator is a space (AFAIK) the separator in German is a dot. This clashes with the floating point separator in other cultures.
I’m used to inputting dot based fractions. But others that are using the things i create not as much and they tend to use either dot or comma, so there’s always some point at which i have to remind them and me again that only one works. Plus, i like the way the unity editor handles it, as you said, allowing both comma and dot. I can’t remember the last time i typed a large number with thousands separators, is that even common?
Maybe it could work assuming that if no comma is found dot signals fractions by default; Or if more than one dot is found the latter is assumed to be the fraction?
It would be nice if the inputfield just handled it the same as the editor basically.
Hi there. Since this modification I can’t enter anymore a decimal number in my Inputfields with the “.” of the numeric pad of my keyboard.
I’m French. So I have to enter now a “,” wich is annoying because it’s not beside the numbers.
Maybe au solution like the following could be ok ?
TMP_InputField.cs:
var separator = Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator;
if (ch == Convert.ToChar(separator) && characterValidation == CharacterValidation.Decimal && !text.Contains(separator))
{
return ch;
}
// Numeric pad separator for non English users.
else if (ch == '.' && characterValidation == CharacterValidation.Decimal && !text.Contains("."))
{
ch = separator;
return ch;
}
I’d like to, but if I change the system language juste in order tu use the numeric “.” button as a french “,” i’m exposed to some unexpected “sides-effects” everywhere in the project, no ? like the date format or measurements (feet, inch, meters) etc…
I’ve made a short script applied on my inputField in order to modifiy the input Before the char validation of TextMeshPro. I don’t know if it’s a good practice but that works :
public class InputFieldConvertDecimalSeparator : MonoBehaviour
{
private void Start()
{
// The verification fonction is executed for each char entered by the user, before TMP validation, and for Decimal InputFields only.
if (this.GetComponent<TMP_InputField>().characterValidation == TMP_InputField.CharacterValidation.Decimal)
{
this.GetComponent<TMP_InputField>().onValidateInput += delegate (string input, int charIndex, char addedChar) { return ValidationDuNewChar(addedChar); };
}
}
private char ValidationDuNewChar(char charToValidate)
{
if (charToValidate == '.')
{
TMP_InputField inputField = this.GetComponent<TMP_InputField>();
if (!inputField.text.Contains(",") && !inputField.text.Contains("."))
{
charToValidate = ',';
}
else if (inputField.text.Contains(",") || inputField.text.Contains("."))
{
charToValidate = '\0';
}
}
return charToValidate;
}
}
[quote=“Egoin, post:12, topic: 795141, username:Egoin”]
I’ve made a short script applied on my inputField in order to modifiy the input Before the char validation of TextMeshPro. I don’t know if it’s a good practice but that works :
[/quote]Now try to parse that text back to float in all possible cultures. Validation makes sure it works correctly, your doesn’t.
The idea to replace the incomming char in onValidateInput is good, and if you combine it with the initial suggestion it also doesn’t break parsing. I modified that script slightly and fixed obvious issues:
using System;
using System.Threading;
using TMPro;
using UnityEngine;
[RequireComponent(typeof(TMP_InputField))]
public class InputDecimalValidator : MonoBehaviour {
private TMP_InputField _inputField;
private void Awake() {
_inputField = GetComponent<TMP_InputField>();
if (_inputField.characterValidation == TMP_InputField.CharacterValidation.Decimal) {
char separator = Convert.ToChar(Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator);
_inputField.onValidateInput += (_, _, addedChar) => {
switch (addedChar) {
case '.':
case ',':
if (_inputField.text.Contains(",") || _inputField.text.Contains(".")) {
return '\0';
}
return separator;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return addedChar;
default:
return '\0';
}
};
}
}
}
There is still one issue: Using this to validate input makes it impossible to replace a selected decimal number by inputing a decimal point/comma (i.e. typing .5 instead of 0.5), because the check for the existing text doesn’t take the selection into account.
It would be better to have the option directly in the Inputfield, especially since doing it this way disables the inbuilt validation entirely, so only replacing the “wrong” separator with the “correct” one doesn’t prevent the user from inputing letters and other symbols, even if the Inputfield is set to decimal. A toggle to treat ‘.’ and ‘,’ inputs equally in decimal numbers would be the minimum, even better would be an option to set the decimal separator(s) manually, and when that separator contains multiple characters, each would be replaced with the current culture’s separator to keep parsing intact.
When have my Text Mesh Pro Input Field set to decimal numbers only, I need to put in commas (I live in germany). On phone, I can’t input it at all, because my phone can only onput 0-9 and “.” and “-”. This means even though i have set my field to decimal numbers, I can only input integers