I’ve sucessfuly managed to fade in text by putting a poly with a gradient texture (black to transparent) over the text, and the moving the gradient poly right. It’s a nice smooth effect and it works out well for solid color backgrounds (see attached picture).
I’m now trying to achieve this over a non solid background. I thought about doing exactly the same way as above, using a different camera, but doing some sort of masking using the alpha from the gradient texture (per pixel masking?). Does anyone know how I can achieve this effect?
Are you aiming specifically for the effect where the text fades in from the left as the texture moves? If you just want the text to fade in, you can change the alpha value of the material’s colour:-
But that will affect the whole text. I want the text to appear letter by letter (achievable either via the method I explained below or by using a GUIText or 3dText and updating the text field), with new letters fading in, instead of just popping in.
This image shows exactly what I’m trying to do (lousy game, but great way of presenting text). The only way I can imagine doing this is by rendering to a texture and then blending that texture in.
Well here’s some pseudo code to get a letter to appear one at a time. I wrote the code in the post, and didn’t compile it. It might need a little changing to get it to work.
You can slightly edit the code for alpha. Even as it is, it would look okay without the fade-in effect. But I know this isn’t what you’re going for. If you can’t come up with ideas to fade in, then respond, and if I have time, I can help you out.
var string : String = "Whatever you want";
var gameString : String = "";
var i : int = 0;
var coolDown : float = .1 // Shows a new letter every .1 second
var timer : float = 0;
function Update () {
if (gameString.length < string.length timer >= coolDown) {
gameString += string[i]
timer = 0;
}
timer += Time.deltaTime;
i++;
//Display the text
}
There are two strings in that code … I’m simply editing a string, which, in it’s barebones is comparable to a vector-array.
It shouldn’t be messy, nor should it be a memory hog.
If you were really concerned with memory, you could just do it by individual characters – but that is on the line of coding in C, and wouldn’t be fun at all.
On a completely unrelated note – that was my 100th post. Woohoo Unity forums!
Quads with vertex colors would do it, but it would mean I’d have to totally bypass GUIText and 3dText, which have all kinds of niceties (e.g. variable width support), so I want to avoid it.
Gamesurgeon, I have no problem coming up with an algo for the letter by letter part. I know that it’ll look good even without the fade in, but I’m polishing my game so much that I also want this part to be perfect
I tried a couple of shaders, trying to get a polygon with a gradient alpha to just affect the text that’s already present on screen, in order to change the alpha, but I gave up after a couple of hours, since I’m really a noob in shaders and all I could get was something that changed the color of the text but also of the background behind it.
So… I’m still looking for a solution. Any more ideas?
Hmm, I don’t know well this will work. It might cause the letters to get bigger – in theory it shouldn’t, but it depends on how accurate unity’s GUI.Text is.
var string : String = "Whatever you want";
var gameString : String = "";
var gameStringFade : String = "";
var i : int = 0;
var coolDown : float = .1 // Shows a new letter every .1 second
var timer : float = 0;
function Update () {
if (gameString.length < string.length timer >= coolDown) {
gameString += string[i]
timer = 0;
}
timer += Time.deltaTime;
i++;
//Display gameString
if (gameString.length < string.length timer >= coolDown) {
gameStringFade = gameString;
gameStringFade += string[i];
// Display gameStringFade with alphaFade in coolDown seconds
}
}
I wrote that really quickly, but the idea is to have 2 strings actually rendered at once. For example, say you wanted to write “Hello”
We only display gameString, normally, and gameStringFade, with alpha. This should, in theory, allow the previous text to remain solid, and the upcoming text to be faded in. However, this could make the text bigger – some bleeding or something.
I though about the exact same algo as you did, but reached the conclusion that I would need an array of strings to fade in, not just one, since multiple letters will have their alpha being changed.
The problem with this approach is the immense number of draw calls I may end up doing, since every string I add will mean a different material.
As aforementioned, theoretically, you only need two strings.
We have the constant string, that provides a full background with no alpha.
Then we have the alpha string, which fades in.
For example, if you have “Hell” on the 100% visible string, you’ll have “Hello” on the fading in string. Lets say, the “Hell” of the fading in string is at a 40% fill. Because the string underneath it is already at 100% visibility, the 40% visibility will not affect it the previous characters, “Hell”. You will only see the “e” fade in.
if you are having trouble understanding this – go into photoshop. Create a dot. Copy the layer. Ensure the bottom layer isat 100% opacity; change the top layer to ~40% opacity. Play around with the opacity of the top layer – no matter what opacity you drag the top layer to, the image will look the same. We are using the same concept.
My code might not perfectly implement it, as I wrote it without compiling in the forums in about 2-3 minutes. But all the psuedocode and ideas are there.
However, as you stated, this is 2 draw calls. If your game has a ton of draw calls already, and you can only afford one, then you’ll have to do some really ugly stuff with shaders and gradients. Otherwise, I’m pretty sure this would be the most efficient way to do it.
If you really need me to do so, I can go into Unity and write this up for you.
If you sincerely believe that two draw calls (two strings) will cause a lag in the iPhone, then please brush up on allocation of memory. I don’t know the amount of default memory allocated for a string, but I can assure it it’s not much – most likely only a few hundred bytes. I would assume Unity would be doing some sort of optimization at build time, such as checking the size of a literal and only allocating that amount, etc.
If one is actually concerned about performance to such an extent then use an array – not a string.
As for emphasis on “every frame,” I don’t know what that’s referring. Everything, unless you use coroutines, are updated every frame. Some more so than others, such as FixedUpdate(). Again, unless you have ~ 30 objects on the screen at once, while this text is being displayed, the iPhone should be O.K…
As for antialiasing – that’s what I was referring to in my first post. While you, in theory, should not see any backwash, I anticipated this might be the case. Only solution would be to up the quality settings. I don’t know the extent to which it might/will look bad, but my guess is it’ll be fine. Probably just a bit crispy on the edges :roll:
I’m not sure to which extent it is a problem. I just ran into performance problems once, and then removed all memory allocations that happen each frame, and that helped.
Here’s an explanation (from dreamora) :
It might not cause a lot of problems, I was just warning about it…
Dreamora and yourself might be right. I’m so used to programming in C, I forget that this is Java, which does the allocation and reallocation of memory for you. It has it’s ups and downs, this being one of the downs.
A way to get around that, would be to use Destroy(); or to use an instance of a string, which should be deleted by itself. I’d have to look into the garbage collection of Java to make sure.
Thanks for reminding me about this! On a second thought, it is more than possible that this could be a memory hog. My last post is retracted
I fully understood what you explained, but as I said you’ll need more than two strings. Using your “Hello” example. By the time you’re on the “Hell” part, the following may happen:
H = 100% Opacity
e = 80% opacity
l = 60% opacity
l = 40% opacity
o (about to appear) = 20% opacity
If the algo waited around for the last letter to fully fade in, either the fade would have to be really quick (and the effect would get lost) or it would take way too long from letter to letter.
Either my pseudo code is wrong, I’m not understand what you’re saying, or you’re not understanding what I’m saying. Haha 8)
First off, all the letters of each string would always be at the same opacity.
All the letters in one string will have an opacity of 100%.
All the other letters in a string will have an opacity of T %, where T depends on time. This is uniform. The entire string will be fading in and out, not just specific letters.
The effect is the letters fade in and out, however, due to the addition of an extra character on the fading-in string.
For example :
Hel Hell – only the “l” will appear faded. You can modify how quickly the string turns from 0-1 in the alpha scale.
After “l” has shown up, the new string will be:
Hell Hello and now the “o” will begin to fade in.
It’s essentially the same type writer effect, but it fades in. Or, it should. In theory.
Try it out – it should only take 5-10 minutes to make. If it doesn’t work, we can come up with something else!
Either my pseudo code is wrong, I’m not understand what you’re saying, or you’re not understanding what I’m saying. Haha 8)
First off, all the letters of each string would always be at the same opacity.
All the letters in one string will have an opacity of 100%.
All the other letters in a string will have an opacity of T %, where T depends on time. This is uniform. The entire string will be fading in and out, not just specific letters.
The effect is the letters fade in and out, however, due to the addition of an extra character on the fading-in string.
For example :
Hel Hell – only the “l” will appear faded. You can modify how quickly the string turns from 0-1 in the alpha scale.
After “l” has shown up, the new string will be:
Hell Hello and now the “o” will begin to fade in.
It’s essentially the same type writer effect, but it fades in. Or, it should. In theory.
Try it out – it should only take 5-10 minutes to make. If it doesn’t work, we can come up with something else!
Hi, you can have every pieces of your text with only one string but I’m not sure if substring() and all thoses if statements will be faster or not :?
var myText : String = "Unity is so great!";
var myTextLength : int = myText.length;
for (i=0; i <= myTextLength; i++) {
print("100% text: " + myText.Substring(0, i));
// If avoid i to be out of array.
if (i <= myTextLength-1) print("80% text:" + myText[i]);
if (i <= myTextLength-2) print("60% text:" + myText[i+1]);
if (i <= myTextLength-3) print("40% text:" + myText[i+2]);
if (i <= myTextLength-4) print("20% text:" + myText[i+3]);
}