0
\$\begingroup\$

Goal

Change the caret to a non-blinking asterisk.

Description

I'm using the TextMeshPro variant of the InputField, and my Unity ver. is 2019.3.

Potential Solutions

Remove Caret

I could remove the caret and manually add an asterisk at the end — and remove it upon submission.

Problem: I don't know how to do that. Caret width doesn't go below 1, and I've yet to see an option to disable it.

Change Caret

Self-explanatory. However, it doesn't appear that customizing the caret character is an option.

Shove The Input Field Off-Scree And Copy Its Value + * To Text On-Screen

I can still use the Input Field (and I need to), but hide it off-screen and put a simple Text field in its place, which will display the Input Field's text + the caret (*).

This could work, but I'm hoping there's a less hacky solution.

\$\endgroup\$
0
\$\begingroup\$

Set Caret Color Alpha = 0

This hews back to Potential Solution #1: Remove Caret.

Once that's done, you need to add a custom caret yourself. Here's my solution, keeping the input field constantly focused, the caret forcibly fixed rightmost, and validating that user input is within a subset of acceptable characters:

using System.Linq;
using UnityEngine;
using TMPro;

public class ChatInputTaker : MonoBehaviour
{
    public TMP_InputField inputField;

    private char[] _acceptableCharacters;
    private int _oldLength;

    #region Constants
    private const int LAST_CHAR_INDEX = 126;
    private const int FIRST_CHAR_INDEX = 32;
    private const string CARET = "*";
    #endregion
    
    private void Awake()
    {
        int inclusiveOffset = 1;
        _acceptableCharacters = new char[LAST_CHAR_INDEX - FIRST_CHAR_INDEX + inclusiveOffset];

        for (int i = 0; i < _acceptableCharacters.Length; i++)
        {
            int charIndex = FIRST_CHAR_INDEX + i;
            char character = (char)charIndex;
            _acceptableCharacters[i] = character;
        }
    }

    private void Start()
    {
        inputField.ActivateInputField();
        inputField.text = CARET;
        PutCaretInPosition();
    }

    private void Update()
    {
        if (Input.anyKey)
        {
            inputField.ActivateInputField();
            PutCaretInPosition();
        }
    }

    public void ValidateChatInput()
    {
        string text = inputField.text;
        
        if (text.Length == CARET.Length)
            return;

        string caretlessText = text.Substring(0, text.Length - CARET.Length);

        // If only deletion occurred, return.
        if (caretlessText.Length - _oldLength < 0)
        {
            _oldLength = caretlessText.Length;
            return;
        }

        int lastIndex = caretlessText.Length - 1;
        char newChar = caretlessText[lastIndex];
        
        if (!_acceptableCharacters.Contains(newChar))
            caretlessText = caretlessText.Substring(0, caretlessText.Length - 1);

        _oldLength = caretlessText.Length;
        SetInputFieldText(caretlessText);
    }

    private void PutCaretInPosition()
    {
        inputField.caretPosition = inputField.text.Length - CARET.Length;
    }

    private void SetInputFieldText(string newText)
    {
        inputField.text = newText + CARET;
        PutCaretInPosition();
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.