mvaganov

CommandLine.cs

Mar 16th, 2017
155
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. using UnityEngine;
  2. using UnityEngine.SceneManagement;
  3. using UnityEngine.EventSystems;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.Text;
  8. using UnityEngine.UI;
  9.  
  10. /// <summary>A basic Command Line emulation for Unity3D v5.5+. Just use 'CommandLine.Log()'</summary>
  11. /// <description>MIT License -- TL;DR -- code is free, don't bother me about it!</description>
  12. public class CommandLine : MonoBehaviour {
  13.  
  14.     /// <summary>example of how to populate the command-line with commands</summary>
  15.     public void PopulateWithBasicCommands() {
  16.         //When adding commands, you must add a call below to registerCommand() with its name, implementation method, and help text.
  17.         AddCommand("help", (args)=>{ Log(" - - - -\n"+CommandHelpString()+"\n - - - -"); },
  18.             "prints this help.");
  19.         AddCommand("reload", (args) => { SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); },
  20.             "reloads current scene.");
  21.         AddCommand("pref", (args) =>{ for(int i=1;i<args.Length;++i){ Log(args[i]+":"+PlayerPrefs.GetString(args[i])); } },
  22.             "shows player prefs value. use: pref [variableName, ...]");
  23.         AddCommand("savepref", (args) =>{
  24.             if(args.Length > 1) {
  25.                 PlayerPrefs.SetString(args[1], (args.Length>2)?args[2]:null);
  26.                 PlayerPrefs.Save();
  27.             } else { Log("missing arguments"); }
  28.         },
  29.             "save player prefs value. use: pref variableName variableValue]");
  30.         AddCommand("resetprefs", (args) =>{ PlayerPrefs.DeleteAll(); PlayerPrefs.Save(); },
  31.             "clears player prefs.");
  32.     }
  33.  
  34.     /// <param name="command">name of the command to add (case insensitive)</param>
  35.     /// <param name="handler">code to execute with this command, think standard main</param>
  36.     /// <param name="help">reference information, think concise man-pages</param>
  37.     public void addCommand(string command, CommandHandler handler, string help) {
  38.         commands.Add(command.ToLower(), new Command(command, handler, help));
  39.     }
  40.  
  41.     public static void AddCommand(string command, CommandHandler handler, string help) {
  42.         Instance.addCommand (command, handler, help);
  43.     }
  44.  
  45.     /// <param name="commands">dictionary of commands to begin using, replacing old commands</param>
  46.     public void SetCommands(Dictionary<string,Command> commands) { this.commands = commands; }
  47.  
  48.     /// <summary>replace current commands with no commands</summary>
  49.     public void ClearCommands() { commands.Clear (); }
  50.  
  51.     /// <summary>command-line handler. think "standard main" from Java or C/C++.
  52.     /// args[0] is the command, args[1] and beyond are the arguments.</summary>
  53.     public delegate void CommandHandler(string[] args);
  54.  
  55.     public class Command {
  56.         public string command { get; private set; }
  57.         public CommandHandler handler { get; private set; }
  58.         public string help { get; private set; }
  59.         public Command(string command, CommandHandler handler, string helpReferenceText) {
  60.             this.command = command; this.handler = handler; this.help = helpReferenceText;
  61.         }
  62.     }
  63.  
  64.     /// <summary>watching for commands *about to execute*.</summary>
  65.     public event CommandHandler onCommand;
  66.     /// <summary>known commands</summary>
  67.     private Dictionary<string, Command> commands = new Dictionary<string, Command>();
  68.     /// <summary>console data that should not be modifiable as user input</summary>
  69.     private string nonUserInput = "";
  70.     /// <summary>the most recent user-input submitted</summary>
  71.     private string recentUserInput;
  72.  
  73.     public string GetMostRecentInput() { return recentUserInput; }
  74.  
  75.     public static string MostRecentInput() { return Instance.GetMostRecentInput(); }
  76.  
  77.     /// <returns>a list of usable commands</returns>
  78.     public string CommandHelpString() {
  79.         StringBuilder sb = new StringBuilder ();
  80.         foreach(Command cmd in commands.Values) { sb.Append(((sb.Length>0)?"\n":"")+cmd.command+": "+cmd.help); }
  81.         return sb.ToString();
  82.     }
  83.  
  84.     /// <summary>resets text to what it should be.</summary>
  85.     /// <returns>presumably the character entered by the user to trigger the refresh</returns>
  86.     public char RefreshText() {
  87.         char typed = '\0';
  88.         if (!sudoAdjustment) {
  89.             sudoAdjustment = true;
  90.             string properOutput = nonUserInput;
  91.             string userInput = GetUserInput ();
  92.             if (userInput == "\n") { userInput = ""; }
  93.             if (inputField.caretPosition > 0 && inputField.caretPosition < nonUserInput.Length
  94.             && inputField.text.Length > nonUserInput.Length) {
  95.                 typed = inputField.text [inputField.caretPosition - 1];
  96.             }
  97.             string refreshedText = properOutput + userInput + ((typed!='\0')?typed.ToString():"");
  98.             SetText (refreshedText);
  99.             nonUserInput = properOutput;
  100.             sudoAdjustment = false;
  101.         }
  102.         return typed;
  103.     }
  104.  
  105.     /// <param name="text">What the the output text should be (turns current user input into text output)</param>
  106.     public void SetText(string text) {
  107.         int cutIndex = CutoffIndexToEnsureLineCount (text, maxLines);
  108.         if (cutIndex != 0) { text = text.Substring (cutIndex); }
  109.         nonUserInput = text;
  110.         if (inputField) { inputField.text = nonUserInput; }
  111.     }
  112.  
  113.     public int CutoffIndexToEnsureLineCount(String s, int maxLines) {
  114.         int lineCount = 0, columnCount = 0, index;
  115.         for (index = s.Length; index > 0; --index) {
  116.             if (s [index - 1] == '\n' || columnCount++ >= maxColumnsPerLine) {
  117.                 lineCount++;
  118.                 columnCount = 0;
  119.                 if (lineCount >= maxLines) { break; }
  120.             }
  121.         }
  122.         return index;
  123.     }
  124.  
  125.     /// <summary>turns current user input into text output</summary>
  126.     private void UseCurrentText() { nonUserInput = inputField.text; }
  127.  
  128.     /// <returns>The output text (not including user input).</returns>
  129.     public string GetText() { return nonUserInput; }
  130.  
  131.     /// <returns>The all text, including user input</returns>
  132.     public string GetAllText() { return inputField?inputField.text:nonUserInput; }
  133.  
  134.     /// <param name="text">Text to add as output, also turning current user input into text output</param>
  135.     public void AddText(string text){ SetText (GetAllText () + text); }
  136.  
  137.     /// <param name="text">line to add as output, also turning current user input into text output</param>
  138.     public void println(string line) { SetText (GetAllText () + line + "\n"); }
  139.  
  140.     public void readLineAsync(DoAfterStringIsRead stringCallback) {
  141.         if (!IsVisible ()) { SetVisibility (true); }
  142.         waitingToReadLine += stringCallback;
  143.     }
  144.  
  145.     /// <summary>Instance.println(line)</summary>
  146.     public static void Log(string line) { Instance.println (line); }
  147.  
  148.     public static void ReadLine(DoAfterStringIsRead stringCallback) { Instance.readLineAsync(stringCallback); }
  149.  
  150.     /// <returns>The user input, which is text that the user has entered (at the bottom)</returns>
  151.     public string GetUserInput() {
  152.         string s = inputField.text;
  153.         int len = s.Length - nonUserInput.Length;
  154.         if (len > 0) {
  155.             recentUserInput = (len > 0) ? s.Substring (nonUserInput.Length, len) : "";
  156.             return recentUserInput;
  157.         } else return "";
  158.     }
  159.  
  160.     public void Run(string commandWithArguments) {
  161.         if (commandWithArguments == null || commandWithArguments.Length == 0) { return; }
  162.         string s = commandWithArguments.Trim (whitespace); // cut leading & trailing whitespace
  163.         string[] args = parseArguments(s);
  164.         if (args.Length < 1) { return; }
  165.         if (onCommand != null) { onCommand (args); }
  166.         Run(args[0].ToLower(), args);
  167.     }
  168.  
  169.     /// <param name="command">Command.</param>
  170.     /// <param name="args">Arguments. [0] is the name of the command, with [1] and beyond being the arguments</param>
  171.     public void Run(string command, string[] args) {
  172.         Command cmd = null;
  173.         // try to find the given command. or the default command. if we can't find either...
  174.         if (!commands.TryGetValue(command, out cmd) && !commands.TryGetValue ("", out cmd)) {
  175.             // error!
  176.             string error = "Unknown command '" + command + "'";
  177.             if (args.Length > 1) { error += " with arguments "; }
  178.             for (int i = 1; i < args.Length; ++i) {
  179.                 if (i > 1) { error += ", "; }
  180.                 error += "'"+args [i]+"'";
  181.             }
  182.             Log(error);
  183.         }
  184.         // if we have a command
  185.         if (cmd != null) {
  186.             // execute it if it has valid code
  187.             if (cmd.handler != null) {
  188.                 cmd.handler (args);
  189.             } else {
  190.                 Log("Null command '" + command + "'");
  191.             }
  192.         }
  193.     }
  194.  
  195.     /// <summary>execute the current input as a command</summary>
  196.     public void Run() { Run(GetUserInput()); }
  197.  
  198.     private static readonly char[] quotes = new char[]{'\'','\"'},
  199.     whitespace = new char[]{' ','\t','\n', '\b', '\r'};
  200.     /// <returns>index of the end of the token that starts at the given index 'i'</returns>
  201.     public static int FindEndToken(string str, int i) {
  202.         bool isWhitespace;
  203.         do {
  204.             isWhitespace = System.Array.IndexOf(whitespace, str [i]) >= 0;
  205.             if(isWhitespace) { ++i; }
  206.         } while(isWhitespace && i < str.Length);
  207.         int index = System.Array.IndexOf(quotes, str [i]);
  208.         char startQuote = (index >= 0)?quotes[index]:'\0';
  209.         if (startQuote != '\0') { ++i; }
  210.         while (i < str.Length) {
  211.             if (startQuote != '\0') {
  212.                 if (str [i] == '\\') {
  213.                     i++; // skip the next character for an escape sequence. just leave it there.
  214.                 } else {
  215.                     index = System.Array.IndexOf(quotes, str [i]);
  216.                     bool endsQuote = index >= 0 && quotes [index] == startQuote;
  217.                     if (endsQuote) { i++; break; }
  218.                 }
  219.             } else {
  220.                 isWhitespace = System.Array.IndexOf(whitespace, str [i]) >= 0;
  221.                 if (isWhitespace) { break; }
  222.             }
  223.             i++;
  224.         }
  225.         if (i >= str.Length) { i = str.Length; }
  226.         return i;
  227.     }
  228.  
  229.     /// <returns>split command-line arguments</returns>
  230.     static string[] parseArguments(string commandLineInput) {
  231.         int index = 0;
  232.         string token;
  233.         List<string> tokens = new List<string> ();
  234.         while (index < commandLineInput.Length) {
  235.             int end = FindEndToken (commandLineInput, index);
  236.             if (index != end) {
  237.                 token = commandLineInput.Substring (index, end - index).TrimStart(whitespace);
  238.                 token = Unescape (token);
  239.                 int qi = System.Array.IndexOf(quotes, token [0]);
  240.                 if (qi >= 0 && token [token.Length - 1] == quotes [qi]) {
  241.                     token = token.Substring (1, token.Length - 2);
  242.                 }
  243.                 tokens.Add (token);
  244.             }
  245.             index = end;
  246.         }
  247.         return tokens.ToArray ();
  248.     }
  249.  
  250.     /* https://msdn.microsoft.com/en-us/library/aa691087(v=vs.71).aspx */
  251.     private readonly static SortedDictionary<char, char> EscapeMap = new SortedDictionary<char, char> {
  252.         {'0','\0'}, {'a','\a'}, {'b','\b'}, {'f','\f'}, {'n','\n'}, {'r','\r'}, {'t','\t'}, {'v','\v'},
  253.     };
  254.     public static string Unescape(string escaped) {
  255.         if (escaped == null) { return escaped; }
  256.         StringBuilder sb = new StringBuilder();
  257.         bool inEscape = false;
  258.         int startIndex = 0;
  259.         for (int i = 0; i < escaped.Length; i++) {
  260.             if (!inEscape) {
  261.                 inEscape = escaped[i] ==  '\\';
  262.             } else {
  263.                 char c;
  264.                 if (!EscapeMap.TryGetValue(escaped[i], out c)) {
  265.                     c = escaped [i]; // unknown escape sequences are literals
  266.                 }
  267.                 sb.Append(escaped.Substring(startIndex, i - startIndex - 1));
  268.                 sb.Append(c);
  269.                 startIndex = i + 1;
  270.                 inEscape = false;
  271.             }
  272.         }
  273.         sb.Append(escaped.Substring(startIndex));
  274.         return sb.ToString();
  275.     }
  276.  
  277.     [Tooltip("Which key toggles (hides/shows) the UI for this object.")]
  278.     public KeyCode toggleKey = KeyCode.BackQuote;
  279.     [Tooltip("ScrollRect container. If null, one will be created, with appropriate settings.")]
  280.     public ScrollRect scrollView;
  281.     [Serializable]
  282.     public class RectTransformSettings {
  283.         public Vector2 anchorMin = Vector2.zero, anchorMax = Vector2.one, offsetMin = Vector2.zero, offsetMax = Vector2.zero;
  284.     }
  285.     [Tooltip("used to size the console Rect Transform on creation")]
  286.     public RectTransformSettings initialRectTransformSettings;
  287.     [Tooltip("InputField element. If null, one will be created, with appropriate settings.")]
  288.     public InputField inputField;
  289.     [Tooltip("The font used. If null, \'Arial.ttf\' (built-in font) will be used.")]
  290.     public Font font;
  291.     [Tooltip("Maximum number of lines to retain.")]
  292.     public int maxLines = 99;
  293.     [Tooltip("lines with more characters than this will count as more than one line.")]
  294.     public int maxColumnsPerLine = 120;
  295.     /// <summary>used to prevent multiple simultaneous toggles of visibility</summary>
  296.     private bool togglingVisiblity = false;
  297.     /// <summary>flag that disables consistency checks, possibly preventing stack-overflow</summary>
  298.     private bool sudoAdjustment = false;
  299.     /// <summary>flag to check if the caret (text focus indicator) has been properly parented</summary>
  300.     private bool inputCaretMoved = false;
  301.     /// <summary>flag to deselect all text if newly activated</summary>
  302.     private bool shouldDeselectAllBecauseOfNewVisibility = false;
  303.     /// <summary>flag to move text view to the bottom when content is added</summary>
  304.     private bool showBottomWhenTextIsAdded = false;
  305.     [Tooltip("If true, will show up immediately")]
  306.     public bool visibleOnStart = true;
  307.  
  308.     #region debug log intercept
  309.     [SerializeField, Tooltip("If true, all Debug.Log messages will be intercepted and duplicated here.")]
  310.     private bool interceptDebugLog = true;
  311.     /// <summary>if this object was intercepting Debug.Logs, this will ensure that it un-intercepts as needed</summary>
  312.     private bool dbgIntercepted = false;
  313.  
  314.     /// <summary>what to do after a string is read.</summary>
  315.     public delegate void DoAfterStringIsRead(string readFromUser);
  316.     /// <summary>if delegates are here, calls this code instead of executing a known a command</summary>
  317.     private event DoAfterStringIsRead waitingToReadLine;
  318.     /// <summary>If this is set, ignore the native CommandLine functionality, and just do this</summary>
  319.     public event DoAfterStringIsRead onInput;
  320.  
  321.     void OnEnable() { SetDebugIntercept (interceptDebugLog); }
  322.  
  323.     void OnDisable() { SetDebugIntercept (false); }
  324.  
  325.     public void SetDebugIntercept(bool intercept) {
  326.              if (intercept && !dbgIntercepted) { Application.logMessageReceived += HandleLog; dbgIntercepted = true; }
  327.         else if (!intercept && dbgIntercepted) { Application.logMessageReceived -= HandleLog; dbgIntercepted = false; }
  328.     }
  329.  
  330.     void HandleLog(string logString, string stackTrace, LogType type) { Log(logString); }
  331.     #endregion
  332.  
  333.     /// <summary>the singleton instance. One will be created if none exist.</summary>
  334.     private static CommandLine instance;
  335.     public static CommandLine Instance {
  336.         get {
  337.             if (instance == null) {
  338.                 if ((instance = FindObjectOfType (typeof(CommandLine)) as CommandLine) == null) {
  339.                     GameObject g = new GameObject ();
  340.                     instance = g.AddComponent<CommandLine> ();
  341.                     g.name = "<" + instance.GetType ().Name + ">";
  342.                 }
  343.             }
  344.             return instance;
  345.         }
  346.     }
  347.  
  348.     /// <summary>Convenience method. Finds the component here, or in a parent object.</summary>
  349.     public static T FindComponentUpHierarchy<T>(Transform t) where T : Component {
  350.         T found = null;
  351.         while (t != null && found == null) { found = t.GetComponent<T> (); t = t.parent; }
  352.         return found;
  353.     }
  354.  
  355.     /// <param name="layer">what Unity layer to set the given object, and all child objects, recursive</param>
  356.     public static void SetLayerRecursive(GameObject go, int layer) {
  357.         go.layer = layer;
  358.         for(int i=0;i<go.transform.childCount;++i){
  359.             Transform t = go.transform.GetChild(i);
  360.             if(t != null) {
  361.                 SetLayerRecursive(t.gameObject, layer);
  362.             }
  363.         }
  364.     }
  365.  
  366.     void Start() {
  367.         CreateUI ();
  368.         inputField.onValueChanged.AddListener((str) => {
  369.             char lastAdded = '\0';
  370.             if (inputField.caretPosition < nonUserInput.Length) {
  371.                 lastAdded = RefreshText();
  372.             }
  373.             bool letterWasAdded = str.Length > nonUserInput.Length;
  374.             if(letterWasAdded) {
  375.                 if(lastAdded == '\0') {
  376.                     lastAdded = str [str.Length - 1];
  377.                 }
  378.                 if (lastAdded == '\n') {
  379.                     if(waitingToReadLine != null) {
  380.                         waitingToReadLine(GetUserInput());
  381.                         waitingToReadLine = null;
  382.                     } else if(onInput != null) {
  383.                         onInput(GetUserInput());
  384.                     } else {
  385.                         Run();
  386.                     }
  387.                     SetText(inputField.text);
  388.                 }
  389.                 scrollView.verticalNormalizedPosition = 0;
  390.                 showBottomWhenTextIsAdded = true;
  391.             }
  392.             if (inputField.caretPosition < nonUserInput.Length) {
  393.                 inputField.caretPosition = nonUserInput.Length;
  394.             }
  395.         });
  396.         // test code
  397.         PopulateWithBasicCommands ();
  398.         if (nonUserInput.Length == 0) { Log(Application.productName + ", v" + Application.version); }
  399.     }
  400.  
  401.     public GameObject CreateUI() {
  402.         Canvas c = FindComponentUpHierarchy<Canvas> (transform);
  403.         if (!c) {
  404.             GameObject CANVAS = new GameObject ("canvas");
  405.             c = CANVAS.AddComponent<Canvas> (); // so that the UI can be drawn at all
  406.             c.renderMode = RenderMode.ScreenSpaceOverlay;
  407.             if(!CANVAS.GetComponent<CanvasScaler>()){
  408.                 CANVAS.AddComponent<CanvasScaler> (); // so that text is pretty when zoomed
  409.             }
  410.             if(!CANVAS.GetComponent<GraphicRaycaster> ()){
  411.                 CANVAS.AddComponent<GraphicRaycaster> (); // so that mouse can select input area
  412.             }
  413.             CANVAS.transform.SetParent (transform);
  414.         }
  415.         if (!scrollView) {
  416.             GameObject scrollViewO = new GameObject ("scrollview");
  417.             scrollViewO.transform.SetParent (c.transform);
  418.             Image img = scrollViewO.AddComponent<Image> ();
  419.             img.color = new Color (0, 0, 0, 0.5f);
  420.             scrollView = scrollViewO.AddComponent<ScrollRect> ();
  421.             scrollView.verticalScrollbarVisibility = ScrollRect.ScrollbarVisibility.AutoHideAndExpandViewport;
  422.             scrollView.verticalScrollbarSpacing = -3;
  423.             scrollView.horizontal = false;
  424.             scrollView.movementType = ScrollRect.MovementType.Clamped;
  425.             if (initialRectTransformSettings == null) {
  426.                 MaximizeRectTransform (scrollView.transform);
  427.             } else {
  428.                 RectTransform r = scrollView.GetComponent<RectTransform> ();
  429.                 r.anchorMin = initialRectTransformSettings.anchorMin;
  430.                 r.anchorMax = initialRectTransformSettings.anchorMax;
  431.                 r.offsetMin = initialRectTransformSettings.offsetMin;
  432.                 r.offsetMax = initialRectTransformSettings.offsetMax;
  433.             }
  434.         }
  435.         if (scrollView.viewport == null) {
  436.             GameObject viewport = new GameObject ("viewport");
  437.             viewport.transform.SetParent (scrollView.transform);
  438.             Image img = viewport.AddComponent<Image> ();
  439.             img.color = new Color(0,0,0,0.5f);
  440.             viewport.AddComponent<Mask> ();
  441.             RectTransform r = MaximizeRectTransform (viewport.transform);
  442.             r.offsetMax = new Vector2 (-16, 0);
  443.             r.pivot = new Vector2 (0, 1);
  444.             scrollView.viewport = r;
  445.         }
  446.         if (scrollView.content == null) {
  447.             GameObject content = new GameObject ("content");
  448.             Text text = content.AddComponent<Text> ();
  449.             text.transform.SetParent (scrollView.viewport.transform);
  450.             if (font == null) {
  451.                 font = Resources.GetBuiltinResource<Font> ("Arial.ttf");
  452.             }
  453.             text.font = font;
  454.             text.supportRichText = false;
  455.             text.verticalOverflow = VerticalWrapMode.Overflow;
  456.             RectTransform r = content.GetComponent<RectTransform>();
  457.             r.anchorMin = new Vector2 (0, 1);
  458.             r.anchorMax = Vector2.one;
  459.             r.offsetMin = r.offsetMax = Vector2.zero;
  460.             r.pivot = new Vector2 (0, 1); // scroll from the top
  461.             inputField = content.AddComponent<InputField> ();
  462.             inputField.lineType = InputField.LineType.MultiLineNewline;
  463.             inputField.textComponent = text;
  464.             inputField.caretWidth = 5;
  465.             ContentSizeFitter csf = content.AddComponent<ContentSizeFitter> ();
  466.             csf.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
  467.             scrollView.content = r;
  468.         } else if (font != null) {
  469.             inputField.textComponent.font = font;
  470.         }
  471.         if (scrollView.verticalScrollbar == null) {
  472.             GameObject scrollbar = new GameObject ("scrollbar vertical");
  473.             scrollbar.transform.SetParent (scrollView.transform);
  474.             scrollbar.AddComponent<RectTransform> ();
  475.             scrollView.verticalScrollbar = scrollbar.AddComponent<Scrollbar> ();
  476.             scrollView.verticalScrollbar.direction = Scrollbar.Direction.BottomToTop;
  477.             RectTransform r = scrollbar.GetComponent<RectTransform> ();
  478.             r.anchorMin = new Vector2(1, 0);
  479.             r.anchorMax = Vector2.one;
  480.             r.offsetMax = Vector3.zero;
  481.             r.offsetMin = new Vector2 (-16, 0);
  482.         }
  483.         if (scrollView.verticalScrollbar.handleRect == null) {
  484.             GameObject slideArea = new GameObject ("sliding area");
  485.             slideArea.transform.SetParent (scrollView.verticalScrollbar.transform);
  486.             RectTransform r = slideArea.AddComponent<RectTransform> ();
  487.             MaximizeRectTransform (slideArea.transform);
  488.             r.offsetMin = new Vector2(10, 10);
  489.             r.offsetMax = new Vector2(-10, -10);
  490.             GameObject handle = new GameObject ("handle");
  491.             Image img = handle.AddComponent<Image> ();
  492.             img.color = new Color (1, 1, 1, 0.5f);
  493.             handle.transform.SetParent (slideArea.transform);
  494.             r = handle.GetComponent<RectTransform> ();
  495.             r.anchorMin = r.anchorMax = Vector2.zero;
  496.             r.offsetMax = new Vector2 (5, 5);
  497.             r.offsetMin = new Vector2 (-5, -5);
  498.             r.pivot = Vector2.one;
  499.             scrollView.verticalScrollbar.handleRect = r;
  500.             scrollView.verticalScrollbar.targetGraphic = img;
  501.         }
  502.         // an event system is required... if there isn't one, make one
  503.         StandaloneInputModule input = FindObjectOfType(typeof(StandaloneInputModule)) as StandaloneInputModule;
  504.         if (input == null) { input = (new GameObject ("<EventSystem>")).AddComponent<StandaloneInputModule> (); }
  505.         // put all UI in the UI layer
  506.         SetLayerRecursive (c.gameObject, LayerMask.NameToLayer ("UI"));
  507.         RefreshText ();
  508.         shouldDeselectAllBecauseOfNewVisibility = true;
  509.         // force visibliity recalculations after UI changes
  510.         scrollView.content.gameObject.SetActive(false);
  511.         scrollView.content.gameObject.SetActive(true);
  512.         SetVisibility (visibleOnStart);
  513.         return scrollView.gameObject;
  514.     }
  515.  
  516.     private static RectTransform MaximizeRectTransform(Transform t) {
  517.         return MaximizeRectTransform(t.GetComponent<RectTransform>());
  518.     }
  519.  
  520.     private static RectTransform MaximizeRectTransform(RectTransform r) {
  521.         r.anchorMax = Vector2.one;
  522.         r.anchorMin = r.offsetMin = r.offsetMax = Vector2.zero;
  523.         return r;
  524.     }
  525.  
  526.     void Update() {
  527.         // toggle visibility on keypress
  528.         if (Input.GetKeyDown(toggleKey)) {
  529.             // and if the keypress showed up in the inputfield, remove it
  530.             string t = inputField.text;
  531.             if (inputField.caretPosition > nonUserInput.Length) {
  532.                 char lastChar = t [inputField.caretPosition - 1];
  533.                 if (Input.GetKey(lastChar.ToString())) {
  534.                     inputField.text = t.Substring (0, inputField.caretPosition - 1) +
  535.                         t.Substring(inputField.caretPosition);
  536.                 }
  537.             }
  538.             ToggleVisibility();
  539.         }
  540.         //Toggle visibility when 5 fingers touch.
  541.         if (Input.touches.Length == 5) {
  542.             if (!togglingVisiblity) {
  543.                 ToggleVisibility();
  544.                 togglingVisiblity = true;
  545.             }
  546.         } else {
  547.             togglingVisiblity = false;
  548.         }
  549.         if (inputField.text.Length <= nonUserInput.Length) {
  550.             RefreshText ();
  551.         }
  552.         // code to fix the input caret, so that it scrolls correctly
  553.         if (!inputCaretMoved) {
  554.             Transform p = inputField.textComponent.transform.parent;
  555.             for (int i = 0; i < p.childCount; ++i) {
  556.                 if (p.GetChild (i).name.EndsWith ("Input Caret")) {
  557.                     Transform caret = p.GetChild (i);
  558.                     caret.transform.SetParent (inputField.textComponent.transform);
  559.                     inputCaretMoved = true;
  560.                     break;
  561.                 }
  562.             }
  563.         }
  564.         if (shouldDeselectAllBecauseOfNewVisibility
  565.         && inputField.selectionAnchorPosition == inputField.text.Length && inputField.selectionFocusPosition == 0) {
  566.             MoveCaretToEnd ();
  567.             shouldDeselectAllBecauseOfNewVisibility = false;
  568.         }
  569.         if (Input.GetAxis ("Mouse ScrollWheel") != 0) {
  570.             showBottomWhenTextIsAdded = scrollView.verticalNormalizedPosition == 0;
  571.         }
  572.         if (showBottomWhenTextIsAdded) { scrollView.verticalNormalizedPosition = 0; }
  573.     }
  574.  
  575.     /// <summary>If shown, hide. If hidden, show.</summary>
  576.     void ToggleVisibility() { SetVisibility(!scrollView.gameObject.activeInHierarchy); }
  577.  
  578.     /// <summary>Moves the caret to the end, clearing all selections in the process</summary>
  579.     public void MoveCaretToEnd() {
  580.         int lastPoint = inputField.text.Length;
  581.         inputField.caretPosition = lastPoint;
  582.     }
  583.  
  584.     public bool IsVisible() {
  585.         return scrollView != null && scrollView.gameObject.activeInHierarchy;
  586.     }
  587.  
  588.     /// <summary>shows (true) or hides (false).</summary>
  589.     public void SetVisibility(bool visible) {
  590.         if (scrollView == null) {
  591.             visibleOnStart = visible;
  592.         } else {
  593.             scrollView.gameObject.SetActive (visible);
  594.             if (visible) {
  595.                 scrollView.verticalNormalizedPosition = 0;
  596.                 inputField.ActivateInputField ();
  597.                 shouldDeselectAllBecauseOfNewVisibility = true;
  598.             } else {
  599.                 MoveCaretToEnd ();
  600.             }
  601.         }
  602.     }
  603. }
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×