I’m doing my own terminal, like simple OS (imagine commodore 64 or fallout4 terminal), its for a game, like you can give it simple commands copy/cp list/ls. I’ve done it quite robust and brute but dont need anything special. Basically it gets input from player, char by char and saves it in list of chars then when enter is pressed it goes and recognizes commands and that all works, for displaying that list of chars i throw chars to string and that string to Text.text and update it to screen. Also works fine but i need my own InputField since terminal has it on focus all the time and allows me much more customization.
THE QUESTION
How to make my own caret (thing that flashes when typing), like i would do it with sprite, some white thick sprite like terminals have it but thing is how to deremine on screen position it should be at, basically how to see where at Text.text i am currently and show white sprite there, or maybe you have better suggestion.
What you can do is check the ‘verts’ collection on it for all the vertices. The verts are in quads, groups of 4, so if you wanted to find a character before the end you need to figure that into your math. But since we just want to find the end of the string we can just use the last vert.
Here is an example:
public class zTest01 : MonoBehaviour
{
public Text TextObject;
public GameObject Cursor;
public float CursorDelay = 0.3f;
public Vector3 CursorOffset;
private string _msg = "";
private float _timer = 0f;
private void Update()
{
//update msg
foreach (char c in Input.inputString)
{
if (c == '\b') // has backspace/delete been pressed?
{
if (_msg.Length != 0)
{
_msg = _msg.Substring(0, _msg.Length - 1);
}
}
else if ((c == '\n') || (c == '\r')) // enter/return
{
_msg += "\r\n";
}
else
{
_msg += c;
}
}
TextObject.text = _msg;
//place cursor
var gen = TextObject.cachedTextGenerator;
if(gen.verts.Count > 0)
{
var v = gen.verts[gen.verts.Count - 1].position;
v = TextObject.transform.TransformPoint(v);
Cursor.transform.position = v + CursorOffset;
}
//do blink
_timer += Time.deltaTime;
if(_timer > CursorDelay)
{
_timer = 0f;
Cursor.SetActive(!Cursor.activeSelf);
}
}
}
Note that the string appending code is very naive and will generate TONS of garbage… it serves only as an example.
As for the getting the cursor position, that should be fine in and of itself.
Note that I have a ‘CursorOffset’ since not all cursors are the same. You might have big fat ones, thin little ones, etc. Use that value to adjust the cursor relative to the end however you like.
Just made new project to test your file, its basically what i need, i may implement later moving left right in command line but for now this works perfectly. ill study it a bit and implement in my project. Thank you very much.
I implemented everything fine and it works perfectly, one thing that bothers me
TextGenerator gen = inputText.cachedTextGenerator; //Get TextGenerator from input
if (gen.verts.Count > 0)
{
Vector3 v = gen.verts[gen.verts.Count - 1].position;
v = inputText.transform.TransformPoint(v);
caret.transform.position = v + caretOffset;
}
this code, after each input from player i make update screen function which is this
inputText.text = "[" + currentIP + "] " + currentDirectory + ": " + CharsToString(command); //Updates players input
historyText.text = ""; //Clears old history text
for (int i = 0; i < history.Count; i++) //Shows all players commands backwards
{
historyText.text += "\n" + history[i];
}
like here i update that text shown to player, but if i put caret update part here, it always is one step before than current situation, putting it in update function works. maybe drawing of text is done later so it cant fix it self until next frame?
Yeah, the code that pulls the information from ‘cachedTextGenerator’ is in the state that only includes the information before Update was called. This means that it doesn’t contain the information from adding in the new characters yet.
If you put in this line before ‘if(gen.verts.Count > 0)’ you should get what you want:
can you please share the project i am very much in need to know how to get this working with the current unity version as the positions are not correct no mater what offset i use thanks