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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .