Search Unity

  1. If you have experience with import & exporting custom (.unitypackage) packages, please help complete a survey (open until May 15, 2024).
    Dismiss Notice
  2. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice

Only make new line when shift+enter is pressed

Discussion in 'UGUI & TextMesh Pro' started by MrIconic, Jan 27, 2018.

  1. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    I want to press only [ENTER] and NOT make a new line.

    Therefore, I could use "Multi Line Submit" and achieve that.

    However, I can no longer make a new line.

    Is it possible to press [SHIFT+ENTER] to make a new line?
     
  2. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, I'm not sure I got the precise order of events here, but something like this might help you:
    (There is a slight visible "selection" of text made.)
    Code (csharp):
    1.  
    2. InputField inputfield;
    3.  
    4.     private void Awake()
    5.     {
    6.         inputfield = GetComponent<InputField>();
    7.        
    8.     }
    9.  
    10.     IEnumerator FieldFix()
    11.     {
    12.         print("Shift + Enter newline.");
    13.         inputfield.ActivateInputField();
    14.  
    15.         yield return null;
    16.  
    17.         inputfield.text += "\n";
    18.         inputfield.MoveTextEnd(false);
    19.     }
    20.     void Update () {
    21.  
    22.         if (EventSystem.current.currentSelectedGameObject == inputfield.gameObject)
    23.         {
    24.             if(Input.GetKey(KeyCode.LeftShift) && Input.GetKeyUp(KeyCode.Return))
    25.             {
    26.                 StartCoroutine(FieldFix());
    27.             }
    28.         }
    29.    }
    I'd suggest using TMP's option to not select all on focus (I am fairly sure that's an option*). :)
     
    ssak2534, Arkade and Ahmad-M like this.
  3. MrIconic

    MrIconic

    Joined:
    Apr 5, 2013
    Posts:
    239
    Figured out a solution.

    I'll write about it here since someone else may be wondering this in the future.... hi future. May appear long but I explained probably more than needed.

    I used playmaker and TextMeshPro - though you can just use the same logic to make a pure code and/or regular inputbox version if needed.


    Create this c# script called InsertText
    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using HutongGames.PlayMaker;
    6. using Tooltip = HutongGames.PlayMaker.TooltipAttribute;
    7. using TMPro;
    8.  
    9. [ActionCategory("String")]
    10. [Tooltip("Adds a string into a string based on integer")]
    11.  
    12.  
    13. public class InsertText : FsmStateAction {
    14.  
    15.  
    16.  
    17.     public FsmString stringToChange;
    18.     public FsmString stringToAdd;
    19.     public FsmString newString = "";
    20.     public FsmInt position;
    21.  
    22.  
    23.     public override void OnEnter()
    24.     {
    25.         DoCommand();
    26.     }
    27.  
    28.     void DoCommand()
    29.     {
    30.    
    31.    
    32.         newString.Value = stringToChange.Value.Insert(position.Value,stringToAdd.Value);
    33.    
    34.         Finish();
    35.      
    36.     }
    37.  
    38. }
    1. Make your Input Field "Multi Line Submit"
      • Do not listen for submit or this may not work properly.
    2. Download the playmaker ecosystem.
      • Download on that page is a link called "EcosystemBrowser Package"
    3. Use the ecosystem to obtain "Get New Line Character"
    4. Action 1 (Start):
      1. Store the Newline Character
    5. Action 2:
      1. Listen for Shift Key (Store bool)
      2. Listen for Enter Key (I used Rewired + Their included Playmaker Actions).
    6. Action 3:
      1. Check if Shift Key bool is true or false.
        • [True] You can link to Action 4 below.
        • [False] You can link to your own actions. (This will be if only Enter and not Shift is pressed, AKA "submit")
    7. Action 3:
      1. Get Inputfield Text
        • This can be done in many ways. However, I used the Get Textmesh Pro UGUI Text mentioned optionally above.
      2. Get Property -> [ TextMeshPro - InputFIeld ] caretPosition
      3. Insert Text (Action)
        • This is the action created from the script above.
        • String To Change = String obtained from 6.1
        • String To Add = Newline Variable from 1
        • New String = A new variable you create
        • Position = Int obtained from 6.2
      4. Int Add (Action)
        • Add to your created caretPostion variable
        • Make this 2.
          • If it's 1 it will usually just return the caret to the beginning of the input box.
      5. Set Property -> [ TextMeshPro - InputFIeld ] text->String
        • Set Value = "New String" in String in 6.3
    8. Action 4:
      1. Wait (Action)
        • Set this to 0.05
        • FINISHED
        • Note: This action is completely necessary because otherwise the caret will not follow the newline and will stay in place regardless of text or line edits.
    9. Action 5:
      1. Set Property -> [ TextMeshPro - InputFIeld ] caretPostion
        • Set Value = Int from 6.2 (that was modified in 6.4)
      2. Call Method -> [ TextMeshPro - InputFIeld ] ActivateInputField()
        • This is needed because pressing enter normally will unfocus the inputfield requiring you to re-select every single time.
    10. Loop back to the state where you originally pressed enter.

    You can now press Shift + Enter in TextMesh Pro to make a new line while Enter will do what you make it do.

    Note: You probably have to disable "OnFocus - Select All" on the inputfield object too.
     
  4. Ahmad-M

    Ahmad-M

    Joined:
    May 19, 2015
    Posts:
    4
    Thanks, It worked perfectly
     
  5. cxode

    cxode

    Joined:
    Jun 7, 2017
    Posts:
    269
    I accomplished this by doing the following in my onSubmit method:

    Code (CSharp):
    1. if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
    2. {
    3.     InputField.text += '\n';
    4.     InputField.ActivateInputField();
    5.     InputField.caretPosition = InputField.text.Length;
    6.     return;
    7. }
    8.  
    9. // Do the thing you'd normally do on submit
    10.  
    This is obviously non-ideal as it's not a generic solution that can work for any and all inputfields.

    Edit: and by the way I think this should be the default, built-in behavior of Multi-Line Submit inputfields. It's kind of silly that we have to code this ourselves
     
    Last edited: Nov 11, 2020
  6. Tehelee

    Tehelee

    Joined:
    Jan 26, 2013
    Posts:
    12
    I was running into an issue where TMP would insert the invalid XML vertical tab character ( 0x0b ) after the OnSubmit event. Additionally I don't see any examples of inserting the newline character at caret positions so I've also included that below. Oh as an added bonus the active selection is replaced with the newline.

    Code (CSharp):
    1. private static readonly string tmpSubmitLineChar = string.Format( "{0}", ( char ) 0x0b );
    2.  
    3. public void OnMessageChanged( string value )
    4. {
    5.     inputMessage.SetTextWithoutNotify( inputMessage.text.Replace( tmpSubmitLineChar, string.Empty ) );
    6.     buttonSubmit.interactable = !string.IsNullOrWhiteSpace( inputMessage.text );
    7. }
    8.  
    9. public void MessageSubmit( string value )
    10. {
    11.     if( inputMessage.isFocused && ( Input.GetKey( KeyCode.LeftShift ) || Input.GetKey( KeyCode.RightShift ) ) )
    12.     {
    13.         int caret = inputMessage.selectionFocusPosition;
    14.         int delete = inputMessage.selectionAnchorPosition - caret;
    15.         string text = inputMessage.text;
    16.  
    17.         if( delete > 0 )
    18.             text = text.Remove( caret, delete );
    19.         text = text.Insert( caret, "\n" );
    20.         inputMessage.SetTextWithoutNotify( text );
    21.  
    22.         inputMessage.ActivateInputField();
    23.         inputMessage.selectionFocusPosition = caret;
    24.         inputMessage.selectionAnchorPosition = caret;
    25.         return;
    26.     }
    27.  
    28.     MessageSubmit();
    29. }
    The TMP Input Field component is configured with a line type of 'Multi Line Submit' and supports line limits.
     
    rayleigh231 likes this.
  7. YayapipiStudio

    YayapipiStudio

    Joined:
    Feb 11, 2017
    Posts:
    9
    Another Simple Solution:

    Code (CSharp):
    1. private void Update()
    2.         {
    3.             if (TargetInput.isFocused)
    4.             {
    5.                 if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
    6.                 {
    7.                     TargetInput.lineType = InputField.LineType.MultiLineNewline;
    8.                 }
    9.                 else
    10.                 {
    11.                     TargetInput.lineType = InputField.LineType.MultiLineSubmit;
    12.                 }
    13.             }
    14.         }
     
    lukasz13 and arimintzu like this.