Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

ideas on creating retro text input field?

Discussion in 'Scripting' started by KUFgoddess, Jan 30, 2018.

  1. KUFgoddess

    KUFgoddess

    Joined:
    Apr 2, 2015
    Posts:
    27
    Hey I am trying to learn how to make an input field in this style below I have gotten started on it visually but how could i begin in C# any tips ? I am using a UI image but if there is anything more effective than please let me know and thanks. I put it in a thread so we can come up with a solution for doing this in unity since I could not find an ounce of information on this topic.

    SNES--Secret of Evermore_May3 15_52_44.png Unity_2018-01-30_04-46-22.png
    here's a gif of what im trying to do.
    https://gfycat.com/ShockingLeanGelada
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Heck... I could think of a way to do this that would require very little C#.

    Use just the UI system. Set up each character as a button, have navigation set to 'automatic', and then for the onClick event of the button you call a method on a script attached to the text field passing along the character for that specific button.

    That script would look something like this:
    Code (csharp):
    1.  
    2. [RequireComponent(typeof(Text))]
    3. public class TextFieldInputController : MonoBehaviour
    4. {
    5.     public Text Text;
    6.  
    7.     void Awake()
    8.     {
    9.         if(Text == null) Text = this.GetComponent<Text>();
    10.     }
    11.  
    12.     public void Append(string character)
    13.     {
    14.         Text.text += character;
    15.     }
    16.  
    17.     public void Backspace()
    18.     {
    19.         var str = Text.text;
    20.         if(str != null && str.Length > 0)
    21.             Text.text = str.Substring(0, str.Length - 1);
    22.     }
    23. }
    24.  
    Of course your backspace button would call backspace instead of Append.

    Done.

    The bulk of the work is setting up the visuals.

    If you don't have a font and don't want each button to use the text portion of it. Just put a background image of your whole thing. And over each character put an invisible button (turn off the image and text part).
     
    KUFgoddess likes this.
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Oh, and if you want that selection cursor. Just have a script that in Update gets the current select object from the EventSystem, and position the cursor over it.

    Here's mine... though mine uses a bit more to it since I allow resizing and various easing with my tween engine. So it's probably overkill:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using UnityEngine.EventSystems;
    4.  
    5. using com.spacepuppy;
    6. using com.spacepuppy.Scenario;
    7. using com.spacepuppy.Tween;
    8.  
    9. using com.spacepuppy.Utils;
    10.  
    11. namespace com.mansion.Entities.UI.Menus
    12. {
    13.  
    14.     public class SelectionBorder : SPComponent
    15.     {
    16.  
    17.         #region Fields
    18.        
    19.         [SerializeField]
    20.         private float _easeDur = 1f;
    21.         [SerializeField]
    22.         EaseStyle _ease;
    23.         [SerializeField]
    24.         private bool _tweenSize;
    25.  
    26.         [SerializeField]
    27.         [UnityEngine.Serialization.FormerlySerializedAs("_onSelectionChange")]
    28.         private Trigger _onSelectionChanged;
    29.  
    30.         [System.NonSerialized]
    31.         private GameObject _currentSelection;
    32.  
    33.         [System.NonSerialized]
    34.         private Tweener _tween;
    35.  
    36.         #endregion
    37.  
    38.         #region CONSTRUCTOR
    39.  
    40.         protected override void OnStartOrEnable()
    41.         {
    42.             base.OnStartOrEnable();
    43.  
    44.             _currentSelection = null;
    45.  
    46.             var ev = EventSystem.current;
    47.             if (ev == null) return;
    48.            
    49.             this.SetCurrent(ev.currentSelectedGameObject, false, true);
    50.         }
    51.  
    52.         #endregion
    53.  
    54.         #region Properties
    55.  
    56.         public float EaseDur
    57.         {
    58.             get { return _easeDur; }
    59.             set { _easeDur = value; }
    60.         }
    61.  
    62.         public EaseStyle Ease
    63.         {
    64.             get { return _ease; }
    65.             set { _ease = value; }
    66.         }
    67.  
    68.         public bool TweenSize
    69.         {
    70.             get { return _tweenSize; }
    71.             set { _tweenSize = value; }
    72.         }
    73.  
    74.         public GameObject CurrentSelection
    75.         {
    76.             get { return _currentSelection; }
    77.         }
    78.  
    79.         public Trigger OnSelectionChanged
    80.         {
    81.             get { return _onSelectionChanged; }
    82.         }
    83.  
    84.         #endregion
    85.  
    86.         #region Methods
    87.  
    88.         public void SetCurrent(GameObject go, bool animate = false, bool suppressOnChangeEvent = false)
    89.         {
    90.             if (go == null) return;
    91.             if (_tween != null)
    92.             {
    93.                 _tween.Stop();
    94.                 _tween = null;
    95.             }
    96.             //if (_currentSelection == go) return;
    97.  
    98.             _currentSelection = go;
    99.             if(animate)
    100.             {
    101.                 var twn = SPTween.Tween(this.transform)
    102.                  .To("position", _currentSelection.transform.position, _easeDur)
    103.                  .Ease(EaseMethods.GetEase(_ease))
    104.                  .UseRealTime();
    105.                 if (_tweenSize)
    106.                 {
    107.                     var trans = _currentSelection.transform as RectTransform;
    108.                     if (trans != null)
    109.                     {
    110.                         twn = twn.To("sizeDelta", trans.sizeDelta, _easeDur);
    111.                     }
    112.                 }
    113.  
    114.                 _tween = twn.Play(true, this);
    115.             }
    116.             else
    117.             {
    118.                 this.transform.position = _currentSelection.transform.position;
    119.                 if (_tweenSize && this.transform is RectTransform)
    120.                 {
    121.                     var trans = _currentSelection.transform as RectTransform;
    122.                     if (trans != null)
    123.                     {
    124.                         (this.transform as RectTransform).sizeDelta = trans.sizeDelta;
    125.                     }
    126.                 }
    127.             }
    128.  
    129.             if (!suppressOnChangeEvent && _onSelectionChanged.Count > 0) _onSelectionChanged.ActivateTrigger(this, null);
    130.         }
    131.  
    132.         #endregion
    133.  
    134.         #region Messages
    135.  
    136.         private void Update()
    137.         {
    138.             if(_tween != null && _tween.IsComplete) _tween = null;
    139.  
    140.             var ev = EventSystem.current;
    141.             if (ev == null) return;
    142.            
    143.             var go = ev.currentSelectedGameObject;
    144.             if (go == null) return;
    145.  
    146.             if (_currentSelection == go)
    147.             {
    148.                 //hack fix - sometimes the display is shaped weird on start, so this will remedy moving UI elements once the game started, but a highlight already set
    149.                 if(_tween == null && Vector3.SqrMagnitude(_currentSelection.transform.position - this.transform.position) > MathUtil.EPSILON)
    150.                 {
    151.                     this.SetCurrent(go, false, true);
    152.                 }
    153.                 return;
    154.             }
    155.  
    156.             this.SetCurrent(go, true, false);
    157.         }
    158.  
    159.         #endregion
    160.  
    161.     }
    162.  
    163. }
    164.  
    A much simpler version that just moves towards it at a speed, and doesn't change size, could look like this:

    Code (csharp):
    1.  
    2. public class SelectionBorder : MonoBehaviour
    3. {
    4.    
    5.     public float LerpSpeed = 1f;
    6.    
    7.     private void Update()
    8.     {
    9.         var ev = EventSystem.current;
    10.         if (ev == null) return;
    11.        
    12.         var go = ev.currentSelectedGameObject;
    13.         if(go == null) return;
    14.        
    15.         var targ = go.transform.position;
    16.         this.transform.position = Vector3.MoveTowards(this.transform.position, targ, this.LerpSpeed * Time.deltaTime);
    17.     }
    18.    
    19. }
    20.  
     
    KUFgoddess likes this.
  4. KUFgoddess

    KUFgoddess

    Joined:
    Apr 2, 2015
    Posts:
    27
    Excellent there it is !I am experimenting right now with this the bottom picture is a screenshot from the project so instead of just text i will set up those buttons like you are saying.