Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by M0rrigan · Feb 12, 2016 at 01:51 PM · c#unity 5uitextrichtextbox

Text UI broken after changing alpha color of single letters

Hi everybody, I'm using a script to change the alpha color of specific letters in a Text UI. Refer to this : http://answers.unity3d.com/questions/1116633/change-alpha-color-of-specific-character-in-a-text.html.

  myText.text = myText.text.Replace(alphabetLetter, "<color=#ffffffxx>"+alphabetLetter+"</color>");

When I change more than six letters at runtime the text disappears and if I select the Text UI I can see this thing inside Text box:

 <color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>H</color><color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>E</color><color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>L</color><color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>L</color>O WOR<color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>L</color><color=#3D3D3DFF>D</color>
 
 <color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>T</color><color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>H</color>IS IS <color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>M</color><color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>E</color>

The text should be "HELLO WORLD THIS IS ME". The bug occurs when I raise the alpha of the "D" letter.

I've checked the documentation http://docs.unity3d.com/Manual/StyledText.html but found nothing about a limit and it seems that nobody else has experienced a similar situation. I suppose this could be a bug, what do you think?

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by JoshuaMcKenzie · Feb 13, 2016 at 05:00 PM

@M0rrigan You're calling text.replace more than once on the string

for example you swap "H" with <color=#3D3D3DFF>H</color> but then you call it again for the "D", and the Replace function is detecting the letters within the color property. giving you:

 color=#3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>3<color=#3D3D3DFF>D</color>FF>H</color>

all of that is just for the H character, very ugly. and this is whats breaking it as now it can't be parsed correctly

String.Replace is NOT what you want to use for this! Try and use RegEx (aka regular expressions). then you can simply run the regex on the base string for the new string of colors. I would recommend that you save the base string somewhere so that if you need to swap colors again you can just use the base (trying to regex a string that already went through a replace is just working hard, not smart) .


Edit: After seeing your class in the comment I see how you were trying to use it. so I rewrote the class to be a little more to how you want it;

First off you want to add this component class to the gameobject that is firing the OnTriggerEnter:

 using UnityEngine;
 using UnityEngine.Events;
 public class TriggerRelay: MonoBehaviour
 {
     private class Delegator<T> : UnityEvent<T>{}
 
     private Delegator<Collider> OnTriggerEnter_ = new Delegator<Collider>();
     private Delegator<Collider> OnTriggerExit_  = new Delegator<Collider>();
 
     public void AttachEnter(UnityAction<Collider> listener)
     {
         OnTriggerEnter_.AddListener(listener);
     }
 
     public void DetachEnter(UnityAction<Collider> listener)
     {
         OnTriggerEnter_.RemoveListener(listener);
     }
 
     public void AttachExit(UnityAction<Collider> listener)
     {
         OnTriggerExit_.AddListener(listener);
     }
 
     public void DetachExit(UnityAction<Collider> listener)
     {
         OnTriggerExit_.RemoveListener(listener);
     }
 
 
     void OnTriggerEnter(Collider other)
     {
         OnTriggerEnter_.Invoke(other);
     }
 
     void OnTriggerExit(Collider other)
     {
         OnTriggerExit_.Invoke(other);
     }
 }

This class is just a relay to pass on trigger collision events to other gameobjects. From my experience in design patterns such as MVC, I've found that its easier if your game logic doesn't explicitly know that a UI exists (but it can have public variables and methods that some classes like a UI might use). the UI can know about the Game logic, but the Game Logic shouldn't know about the UI. Keeping this in mind will help a lot in preventing you from coding into some traps later on (cause you're minimizing dependency, and allows the game logic to have complete control over the game play as it should).

now as for that other class that will be going on Gameobject that has the Text Component:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text.RegularExpressions;
 using UnityEngine;
 using UnityEngine.UI;
 
 
 public class ColorText: MonoBehaviour
 {
     public TriggerRelay relay;
 
     public IDictionary<string,string> characterMap = new Dictionary<string,string>()
     {
         {"H","<color=#003D3DFF>H</color>"},
         {"E","<color=#3D003DFF>E</color>"},
         {"L","<color=#3D3D00FF>L</color>"},
         {"O","<color=#DD3D3DFF>O</color>"},
         {"W","<color=#3DDD3DFF>W</color>"},
         {"R","<color=#3D3DDDFF>R</color>"},
         {"D","<color=#8D3D3DFF>D</color>"},
         {"I","<color=#3D8D3DFF>I</color>"},
         {"S","<color=#3D3D8DFF>S</color>"},
         {"M","<color=#FFFFFFFF>M</color>"}
     };
     
     Text myText;
     string baseString;
     bool isFormatted;
 
     void Awake()
     {
         myText = GetComponent<Text>();
         isFormatted = false;
     }
 
     void OnEnable()
     {
         if(relay)
         {
             relay.AttachEnter(WhenTriggerEnter);
             relay.AttachExit(WhenTriggerExit);
         }
         isFormatted = false;
         baseString = myText.text;
     }
 
     void OnDisable()
     {
         if(relay)
         {
             relay.DetachEnter(WhenTriggerEnter);
             relay.DetachExit(WhenTriggerExit);
         }
         isFormatted = false;
         myText.text = baseString;
     }
 
 
     public void ChangeText(string newText)
     {
         myText.text = baseString = newText;
         if(isFormatted)
         {
             Format();
         }
     }
 
     void Format()
     {
         Regex regex 
             = new Regex (String.Join ("|", characterMap.Keys.Select(c => Regex.Escape(c)).ToArray()));
         myText.text = regex.Replace (baseString, m => characterMap [m.Value]);
     }
     
     void WhenTriggerEnter(Collider o)
     {
         Format();
         isFormatted = true;
     }
     
     void WhenTriggerExit(Collider o)
     {
         myText.text = baseString;
         isFormatted = false;
     }
 
 }

just drag in the reference of the TriggerRelay onto the component in the inspector (or if you are instantiating it at runtime you can set it then)

Comment
Add comment · Show 4 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image M0rrigan · Feb 13, 2016 at 05:45 PM 0
Share

Thank you @Joshua$$anonymous$$c$$anonymous$$enzie but I get some errors with your code. Copied/pasted in a new cs, added using UnityEngine; on top and fixed "$$anonymous$$onoBehavior" with "$$anonymous$$onoBehaviour", and this is what the console prints:

alt text

I've also tried to change the variables with the ones i'm currently using, but it doesn't work. Here's my code with your changes:

 using UnityEngine;
 using System.Collections.Generic;
 using UnityEngine.UI;
 using System.Text.RegularExpressions;
 
 public class ColorfulText: $$anonymous$$onoBehaviour
 {
     static IDictionary<string,string> character$$anonymous$$ap = new Dictionary<string,string>()
     {
         {"H","<color=#003D3DFF>H</color>"},
         {"E","<color=#3D003DFF>E</color>"},
         {"L","<color=#3D3D00FF>L</color>"},
         {"O","<color=#DD3D3DFF>O</color>"},
         {"W","<color=#3DDD3DFF>W</color>"},
         {"R","<color=#3D3DDDFF>R</color>"},
         {"D","<color=#8D3D3DFF>D</color>"},
         {"I","<color=#3D8D3DFF>I</color>"},
         {"S","<color=#3D3D8DFF>S</color>"},
         {"$$anonymous$$","<color=#FFFFFFFF>$$anonymous$$</color>"}
     };
     static Regex regex = new Regex (System.String.Join ("|", character$$anonymous$$ap.$$anonymous$$eys));
 
     public GameObject letterText;
     string alphabetLetter;
 
     void Awake()
     {
         Text myText = letterText.GetComponent<Text> ();
         alphabetLetter = myText.text;
         Format ();
     }
 
     public void ChangeText(string newText)
     {
         alphabetLetter = newText;
         Format ();
     }
 
     void Format()
     {
         myText =  myText.text.regex.Replace (alphabetLetter, m => character$$anonymous$$ap [m.Value]);
     }
 
 }

And here's the full code I was using when the problem occurred:

 using UnityEngine;
 using System.Collections;
 using UnityEngine.UI;
 
 public class ColorText : $$anonymous$$onoBehaviour 
 {
 
 
     public string alphabetLetter;
     public GameObject letterText;
 
 
 
 
     void Start () 
     {
         letterText = GameObject.FindWithTag ("LetterText");
     }
 
     void OnTriggerEnter(Collider other) 
     {
         Text myText = letterText.GetComponent<Text> ();
 
             myText.text = myText.text.Replace(alphabetLetter, "<color=#3D3D3DFF>"+alphabetLetter+"</color>");
           }
 }
 


avatar image M0rrigan · Feb 14, 2016 at 09:12 AM 0
Share

Okay, now I don't get any error, but the result is different from what I need. In fact, it replaces the specific letter to the whole text. The mechanic is: I have a hidden text in a scene, and I change alpha of specific letters to reveal that gradually. $$anonymous$$y text gameobject contains the whole sentence, that's why I need to act on the single letters' alpha color.

I've tried to change this: myText.text = regex.Replace (baseString, m => character$$anonymous$$ap [m.Value]);

into this: myText.text = myText.text.regex.Replace (baseString, m => character$$anonymous$$ap [m.Value]); But it doesn't work.

avatar image JoshuaMcKenzie M0rrigan · Feb 14, 2016 at 01:32 PM 0
Share

@$$anonymous$$0rrigan seems the full intent of the class still hasn't been fully disclosed. However, since the original question was answered (it was breaking not because of some limit but due to bad parsing from reusing Replace multiple times), this is getting off-topic. Addressing this issue would be better handled in the Unity Forums (and there i don't have to worry about character limits in the comments). Please provide a link to the created thread here for posterity.

There we can ask for some more specifics like where/when/how are you setting the alphabetLetter, and can the class be a singleton. All of which would deter$$anonymous$$e how to solve this issue. From what i'm reading here you're looking to only change one letter at a time, not all instances of that letter. I can think of a number of ways of solving this problem but they all depend on how you intend to use the class.

avatar image M0rrigan JoshuaMcKenzie · Feb 14, 2016 at 04:23 PM 0
Share

Okay, thank you. See you there: http://forum.unity3d.com/threads/help-with-my-script-to-change-text-alpha-color-via-regex.386034/

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Ui text to string ? 1 Answer

[SOLVED] Why is text not appearing? 2 Answers

How to change color of animated Text component 2 Answers

Inputfield text to String variable 1 Answer

Disable and Enable UI text in function 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges