Author Topic: Injecting color codes into UIInput Label  (Read 3945 times)

MastaC

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 2
    • View Profile
Injecting color codes into UIInput Label
« on: January 16, 2016, 12:15:21 PM »
Hi guys,

I'm writing an in-game Lua scripting system for my game and trying to implement syntax highlighting. Right now I'm listening for the UIInput's onChange, taking the UIInput.value, and inserting the formatted text into the UIInput.label.text. That works great and keeps the text formatted without tampering with the UIInput's actual value, which is read and saved to a .lua file.

Unfortunately this clears the formatting any time I click in or out of the UIInput. Ok, so I add UICamera.onSelect and process the text again each time the Input is selected or deselected. That part works great when deselected the Input, but not when selecting.

I can't, for the life of me, get the text to consistently stay color formatted. Am I going the wrong direction by taking UIInput.value, processing it, and assigning that text to its UILabel? What would be the best method of getting this done cleanly?

Thanks!

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Injecting color codes into UIInput Label
« Reply #1 on: January 16, 2016, 01:51:05 PM »
Obvious question first... why are you implementing LUA?

C# is already a scripting language, and it supports run-time code compilation. I do this in Windward. The ability to execute run-time code is awesome. I can do stuff like this in chat:
  1. /exe GameObject.Find("Aren Mook").GetComponent<GameShip>().AddBuff("BuffHull", 1f, 1000f);
I also added the ability to run-time compile and execute C# files in the same fashion. C# is a very powerful language. All you need to do is grab "Mono.CSharp.dll" from the Unity editor folder and put it in your project's Plugins folder.
  1. using UnityEngine;
  2. using System.Reflection;
  3. using TNet;
  4. using Mono.CSharp;
  5.  
  6. static class RuntimeCodeExample
  7. {
  8.         static Assembly[] mCachedAssemblies = null;
  9.  
  10.         static public object Execute (string code)
  11.         {
  12.                 if (mCachedAssemblies == null)
  13.                 {
  14.                         mCachedAssemblies = System.AppDomain.CurrentDomain.GetAssemblies();
  15.  
  16.                         Mono.CSharp.Evaluator.Init(new string[] { });
  17.  
  18.                         for (int i = 0, imax = mCachedAssemblies.Length; i < imax; ++i)
  19.                         {
  20.                                 Assembly assembly = mCachedAssemblies[i];
  21.                                 if (assembly.FullName.Contains("Mono.")) continue;
  22.                                 if (assembly.FullName.Contains("UnityEditor")) continue;
  23.                                 if (assembly.FullName.Contains("Cecil")) continue;
  24.  
  25.                                 try
  26.                                 {
  27.                                         Mono.CSharp.Evaluator.ReferenceAssembly(assembly);
  28.                                 }
  29.                                 catch (System.Exception ex)
  30.                                 {
  31.                                         Debug.LogError(assembly.FullName + "\n" + ex.Message);
  32.                                         return null;
  33.                                 }
  34.                         }
  35.                 }
  36.  
  37.                 System.Text.StringBuilder sb = new System.Text.StringBuilder("");
  38.                 sb.AppendLine("using System;");
  39.                 sb.AppendLine("using UnityEngine;");
  40.                 Mono.CSharp.Evaluator.Compile(sb.ToString());
  41.                
  42.                 if (string.IsNullOrEmpty(code)) return null;
  43.                 if (code[code.Length - 1] != ';') code += ";";
  44.  
  45.                 object result = null;
  46.                 bool result_set = false;
  47.  
  48.                 try
  49.                 {
  50.                         string s = Mono.CSharp.Evaluator.Evaluate("{\n" + code + "\n}", out result, out result_set);
  51.                         if (!result_set && !string.IsNullOrEmpty(s)) Debug.LogError("Syntax error: " + s);
  52.                 }
  53.                 catch (System.Exception ex)
  54.                 {
  55.                         Debug.LogError(ex.Message);
  56.                 }
  57.                 return result_set ? result : null;
  58.         }
  59. }
But anyway... in regards to your original question... You need to use two labels for something like this. Type in one, output formatted text in another. NGUI's input was written with a limitation of it not supporting emoticons / bbcode while you are typing in the same line due to how complicated it gets when you take formatting / selection into consideration. Using two labels will do the trick though.

MastaC

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • Posts: 2
    • View Profile
Re: Injecting color codes into UIInput Label
« Reply #2 on: January 20, 2016, 10:37:18 PM »
Thank you!

I created two UILabels and layered them directly on top of each other. Changed the background label's text to be the same color as the background so I could keep the caret. Other label is processed directly on top of it. Works like a charm.

As for Lua, frankly I didn't know you could work with C# at runtime! We'd have to see if this is viable for us, as we need fine control over what the player can and can't do. Thanks for giving us that insight though.

Cheers!

ArenMook

  • Administrator
  • Hero Member
  • *****
  • Thank You
  • -Given: 337
  • -Receive: 1171
  • Posts: 22,128
  • Toronto, Canada
    • View Profile
Re: Injecting color codes into UIInput Label
« Reply #3 on: January 25, 2016, 10:07:18 PM »
Controlling what's possible or not is a trivial matter. Since all code comes in text form, you can just do a few basic checks on it validating its eligibility. For example:
  1.                 if (code.IndexOf("Directory") != -1) return;
  2.                 if (code.IndexOf("File") != -1) return;
  3.                 if (code.IndexOf("Reader") != -1) return;
  4.                 if (code.IndexOf("Stream") != -1) return;
  5.                 if (code.IndexOf("Assembly") != -1) return;
  6.                 if (code.IndexOf("Evaluator") != -1) return;
  7.                 if (code.IndexOf("Evaluate") != -1) return;
  8.                 if (code.IndexOf("SetAdmin") != -1) return;
  9.                 if (code.IndexOf("BeginSend") != -1) return;
  10.                 if (code.IndexOf("EndSend") != -1) return;
  11.                 if (code.IndexOf("BeginPacket") != -1) return;
  12.                 if (code.IndexOf("EndPacket") != -1) return;