Just like Blender, allow the user to type numbers while scaling, rotating or translating as a multiplier.
I already wrote the code for a simple keyboard recorder. The problem has been finding an elegant way to add this to tools without having to copy and paste the logic everywhere. Something almost as simple as a C# property for the tools that support this feature (or an input focus related thing).
#if UNITY_EDITOR
using System;
using UnityEditor;
using UnityEngine;
namespace AeternumGames.ShapeEditor
{
/// <summary>Processes keyboard numbers for typing multipliers during active tools and widgets.</summary>
[Serializable]
public class NumericKeyboardRecorder
{
/// <summary>The accumulated string of characters.</summary>
private string accumulator = "";
private float lastValidFloat = 0.0f;
/// <summary>Gets or sets (clears) whether the user has typed a value using the keyboard.</summary>
public bool hasValue
{
get
{
if (accumulator.Length == 0) return false;
return true;
}
set
{
if (!value)
Reset();
}
}
/// <summary>The last valid value typed assuming <see cref="hasValue"/> is true.</summary>
public float value => lastValidFloat;
/// <summary>The text typed assuming <see cref="hasValue"/> is true.</summary>
public string text => accumulator;
/// <summary>Must be called on key down events.</summary>
public bool OnKeyDown(KeyCode keyCode)
{
var character = (char)keyCode;
// add floating point related characters to the accumulator.
if (ValidateCharacter(character))
{
accumulator += character;
UpdateValue();
return true;
}
if (hasValue)
{
// backspace can be used to remove the last character.
if (keyCode == KeyCode.Backspace)
{
OnBackspace();
UpdateValue();
return true;
}
// minus can be used to negate the number.
if (keyCode == KeyCode.Minus)
{
OnMinus();
UpdateValue();
return true;
}
}
return false;
}
// whitelist the input characters related to floating point numbers.
private bool ValidateCharacter(char character)
{
switch (character)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
return true;
}
return false;
}
private void OnBackspace()
{
if (accumulator.Length == 0) return;
accumulator = accumulator.Remove(accumulator.Length - 1, 1);
}
private void OnMinus()
{
if (accumulator.ContainsInvarianCulture("-"))
accumulator = accumulator.Replace("-", "");
else
accumulator = "-" + accumulator;
}
private void UpdateValue()
{
if (ExpressionEvaluator.Evaluate(accumulator, out float number))
lastValidFloat = number;
}
/// <summary>Resets the current input.</summary>
public void Reset()
{
accumulator = "";
lastValidFloat = 0.0f;
}
}
}
#endif
Just like Blender, allow the user to type numbers while scaling, rotating or translating as a multiplier.
I already wrote the code for a simple keyboard recorder. The problem has been finding an elegant way to add this to tools without having to copy and paste the logic everywhere. Something almost as simple as a C# property for the tools that support this feature (or an input focus related thing).