COOL TEXT EFFECTS IN UNITY 2020 | TEXTMESH PRO (FREE)

Поділитися
Вставка
  • Опубліковано 3 жов 2024

КОМЕНТАРІ • 79

  • @afifzughayer5935
    @afifzughayer5935 3 роки тому +11

    Super good tutorial.
    I've been struggling with applying text effect in TMP, and this tutorial came in clutch!
    It's extremely quick, easy to understand, and straight to the point!
    Thank man! You really helped me and others out!

    • @Madalaski
      @Madalaski  3 роки тому +2

      No worries, thanks for enjoying it!

  • @haemogoblin7006
    @haemogoblin7006 4 роки тому +7

    When one legend leaves behind a legacy, more emerge from the beyond! Glad to find a new senpai to tut me thru!

    • @Madalaski
      @Madalaski  4 роки тому +4

      Oh friend, I'm no Brackeys that's for sure. We cannot replace the legends that came before us but we do our best to live up to them.
      But hey, if there's anything you'd like me to cover in a tutorial, give me a shout!

    • @haemogoblin7006
      @haemogoblin7006 4 роки тому

      @@Madalaski true true! None cud replace em but teaching others the stuff u know is just so humane and humble of y'all imo!
      Ps idk what certain topic to point out in Unity but a series on the current ways of networking in it wud be immensely helpful (if it's within the scope of your interests of course)! Anyway keep the Shader tuts flowing in and with it, anything Unity would be welcomed by the majority I guess XD! Great job senpai!

  • @dethswurl117
    @dethswurl117 2 роки тому +8

    Thank you so much for this tutorial!
    *But I would highly recommend skipping spaces:*
    for (int i = 0; i < charCount; i++)
    {
    TMP_CharacterInfo c = textMesh.textInfo.characterInfo[i];
    // Skip spaces as they don't have any vertices.
    //
    // They also have a vertexIndex of zero which causes confusing
    // issues with modifications to the first letter.
    if (c.character == ' ')
    {
    continue;
    }
    ...
    }

    • @DreamMixGames
      @DreamMixGames 2 роки тому +1

      Thank you so much! The tutorial was awesome, but this saved me so much time.

  • @JacksonAcademy1
    @JacksonAcademy1 3 роки тому +5

    Thanks! I was going to buy a $50 asset from the asset store, but I found this awesome tutorial!

    • @Madalaski
      @Madalaski  3 роки тому +1

      Always happy to help save money!

    • @JacksonAcademy1
      @JacksonAcademy1 3 роки тому

      @@Madalaski I'm trying to do an effect where I display a score counter, and each time a number of the score changes, I play a little animation for that character. The characters that stay the same don't animate.

    • @JacksonAcademy1
      @JacksonAcademy1 3 роки тому

      @@Madalaski Like this game made by me: sullystudios.itch.io/space-all-alone

    • @Madalaski
      @Madalaski  3 роки тому

      @@JacksonAcademy1 Aw nice, I bet this'll look sick 😎😎😎

    • @JacksonAcademy1
      @JacksonAcademy1 3 роки тому

      @@Madalaski Wait lol i meant to ask for help, how do I detect if a character has changed

  • @spyschannel8000
    @spyschannel8000 7 місяців тому +1

    Amazing video, very concise, definitely the best video about this topic out there :)

  • @byDheimid
    @byDheimid 3 місяці тому

    There is very little documentation about this, and it is very well explained in your video! It has helped me a lot, however it is still difficult for me to implement it by characters separately... You could upload more tutorials and different types of animations when typing texts, it would be very useful!

  • @vvbgamedevx11
    @vvbgamedevx11 2 місяці тому

    Thanks for the vid. You got a sub for this.

  • @vimtutorials5234
    @vimtutorials5234 3 роки тому +3

    This tutorial was incredible thank you!
    I took the liberty of modifying the code a bit to add the ability to apply this effect to only one part of your whole text! (needed it for my game) and added some quality of life bools :)
    (again, I modified Madalaski code so props to him!)
    Here is the complete code for anyone that wants it:
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEngine.UI;
    using TMPro;
    public class RainbowText : MonoBehaviour
    {
    //Variables for Word Change
    [SerializeField] bool applyOnlyToSelection;
    [TextArea(5,5)] //make this area bigger if you need to add more lines
    [SerializeField] string textToChangeColor;
    int specificWordIndex;
    //Variables for Text Change
    TMP_Text textMesh;
    Mesh mesh;
    Vector3[] vertices;
    List wordIndexes;
    List wordLengths;
    //Wobbling Variables
    Vector3 offset;
    [SerializeField] bool wobbleText = false;
    [SerializeField] float wobblingSpeed = 1f;
    //global Variables
    TMP_Text tempTextMesh;
    string tempString;
    //Color Variables
    [SerializeField] float colorSpeed = 2f;
    public Gradient rainbow;
    // Start is called before the first frame update
    void Start()
    {
    textMesh = GetComponent();
    wordIndexes = new List();
    wordLengths = new List();
    if (applyOnlyToSelection)
    {
    char[] tempChars = textToChangeColor.ToLower().ToCharArray();
    tempString = textMesh.text.ToLower();
    for (int i = 0; i < tempString.Length; i++)
    {
    if(tempString[i].CompareTo(tempChars[0]) == 0) //check if the first letter of the Selection is found
    {
    for (int j = 1; j < tempChars.Length; j++) //Go over every character in our selection
    {
    if(tempString[i + j].CompareTo(tempChars[j]) != 0) //if next character is not the character in our selection, go back to the 1st For Loop
    {
    break;
    }

    if(j == tempChars.Length - 1) //if every character was correct, We found our selection!!
    {
    print("Found the word!");
    wordIndexes.Add(i);
    wordLengths.Add(tempChars.Length);
    tempString = textToChangeColor;
    return;
    }
    }
    }
    //Our selection was not found, Script will deactivate itself because it wont do anything anyways
    if (i == tempString.Length - 1) { print("Word not found!"); this.enabled = false; }
    }
    }
    else
    {
    wordIndexes.Add(0); //wordIndexes needs to start with an index of 0
    tempString = textMesh.text;
    for (int index = tempString.IndexOf(' '); index > -1; index = tempString.IndexOf(' ', index + 1))
    {
    wordLengths.Add(index - wordIndexes[wordIndexes.Count - 1]);
    wordIndexes.Add(index + 1);
    }
    wordLengths.Add(tempString.Length - wordIndexes[wordIndexes.Count - 1]);
    }
    }
    // Update is called once per frame
    void Update()
    {
    textMesh.ForceMeshUpdate();
    mesh = textMesh.mesh;
    vertices = mesh.vertices;
    Color[] colors = mesh.colors;
    for (int w = 0; w < wordIndexes.Count; w++)
    {
    int wordIndex = wordIndexes[w];
    if(wobbleText) offset = Wobble(Time.time * wobblingSpeed + w);
    for (int i = 0; i < wordLengths[w]; i++)
    {
    TMP_CharacterInfo c = textMesh.textInfo.characterInfo[wordIndex + i];
    int index = c.vertexIndex;
    if (applyOnlyToSelection) { if (index == 0) continue; } //if there is a blank character, go to the next character instead
    colors[index] = rainbow.Evaluate(Mathf.Repeat(Time.time * colorSpeed - vertices[index].x * 0.001f, 1f));
    colors[index + 1] = rainbow.Evaluate(Mathf.Repeat(Time.time * colorSpeed - vertices[index + 1].x * 0.001f, 1f));
    colors[index + 2] = rainbow.Evaluate(Mathf.Repeat(Time.time * colorSpeed - vertices[index + 2].x * 0.001f, 1f));
    colors[index + 3] = rainbow.Evaluate(Mathf.Repeat(Time.time * colorSpeed - vertices[index + 3].x * 0.001f, 1f));
    if (wobbleText)
    {
    vertices[index] += offset;
    vertices[index + 1] += offset;
    vertices[index + 2] += offset;
    vertices[index + 3] += offset;
    }
    }
    }
    mesh.vertices = vertices;
    mesh.colors = colors;
    textMesh.canvasRenderer.SetMesh(mesh);
    }
    Vector2 Wobble(float time)
    {
    return new Vector2(Mathf.Sin(time * 3.3f), Mathf.Cos(time * 2.5f));
    }
    }

    • @Madalaski
      @Madalaski  3 роки тому

      This is a really cool solution! Mad props!
      I imagine an easier method would be to iterate through the WordInfo information in TextInfo property. Then you could just compare each word in there to the word you're trying to animate rather than having to go character by character. Or if you set the index of the word you want to animate you could go straight there with TextInfo.WordInfo[w].GetWord() but I don't know if that's better for your purposes or not.

    • @vimtutorials5234
      @vimtutorials5234 3 роки тому +1

      @@Madalaski Thank you! That is actually the first route I took (WordInfo[w].GetWord()) but was having trouble getting it to work properly, I definitely think it could be improved with that, I just took this route Im more familiar with, still fairly new to all the possibilities with TMPro :)

    • @Madalaski
      @Madalaski  3 роки тому +1

      @@vimtutorials5234 No worries just figured I'd point it out!

    • @BenightedAlizar
      @BenightedAlizar 2 роки тому

      This is really cool! Thank you!
      I did notice a bug, though: If the first letter in the text is part of the selection it is skipped.
      Still, this is really nice. I think I'll modify it a bit by moving it inside a Coroutine and use it in my current project.

  • @happytofu5
    @happytofu5 Рік тому

    Such a cool effect, looks awesome!

  • @Visuwyg
    @Visuwyg 3 роки тому +3

    Where is that triangles-in-a-trenchcoat quote from, cracked me up XD

  • @LostM00nOfPoosh
    @LostM00nOfPoosh 2 роки тому

    LMAO "A square is just 2 triangles in a trench coat." I like that lol

  • @creativecipher
    @creativecipher 6 місяців тому

    Great tutorial, looks great :)
    Only weird thing is that for some reason the first letter of a paragraph moves WAY more than all of the other ones, only sometimes though...

  • @worldofretrogaming2248
    @worldofretrogaming2248 Рік тому

    exactly what I was looking for, great!

  • @ObviousDev
    @ObviousDev 3 роки тому +1

    Damn, this tutorial was helpful! Thanks a lot :D

  • @nandorantal1228
    @nandorantal1228 3 роки тому +3

    By half of the video i checked the speed but i realized its normal :D

  • @bini7203
    @bini7203 2 роки тому

    Oh wow, what a neat little tutorial. Thanks!

  • @karandhaliwal9049
    @karandhaliwal9049 2 роки тому

    This actually helped me so much, thank you

  • @Herbherth
    @Herbherth 2 роки тому

    Nice video, thanks! I was having a trouble making an effect for character because for some reason the first character always seems to take double the effect. If anyone having the same issue the fix is easy: instead of making a looping through the characters of the sentence, I just did a loop through all vertex:
    for (int i = 1; i < text.mesh.vertexCount; i++)
    {
    vertices[i] += Wobble();
    }
    The rest is the same and it works like a charm. Also, I did a fast test and it seems the loop is always the same size, doesn't matter how long or short your text is.

    • @Madalaski
      @Madalaski  2 роки тому +2

      Hey there pretty sure you need to use int i = 0 at the start of that for loop. Don't forget your zero indexing!

    • @Herbherth
      @Herbherth 2 роки тому

      @@Madalaski you are right, I was doing some tests to check the first letter and forgot to go back to 0

  • @DonCrafts1
    @DonCrafts1 4 роки тому +3

    New sub here :) amazing content boi

    • @Madalaski
      @Madalaski  4 роки тому +1

      Cheers! Stick around for new content soon!!!!!

  • @BROCK06
    @BROCK06 2 роки тому +1

    Where do we put the script? All the code is written correctly and I also put it on my text that uses TMPro but nothing happens.

  • @MarioRamosMontesinos
    @MarioRamosMontesinos 3 роки тому +1

    Nice video!

  • @jzolate7600
    @jzolate7600 Рік тому +1

    Thanks for your tutotial!
    I don't even have to type anything and it works !

  • @hernancrespo1998
    @hernancrespo1998 3 роки тому +1

    Thanks thanks thanks!!!

  • @hrishikeshthakker3473
    @hrishikeshthakker3473 4 роки тому +4

    Uhhhhhhh let me yeeeeeeet that code
    Yeeeeeeeeeeeeeet

    • @Madalaski
      @Madalaski  4 роки тому +2

      Yeet away. Yeet away.

  • @ojtaylor2249
    @ojtaylor2249 4 роки тому +1

    good one

  • @promultigamer1997
    @promultigamer1997 2 роки тому +1

    do you know a way that I can call these effects using tags in textmeshpro... would be cool to have specific words wobble instead of the whole objects string...

    • @zORg_alex
      @zORg_alex Рік тому

      Same as in words example. Find your word indexes and do stuff with it.

  • @fr4nk0
    @fr4nk0 2 роки тому +1

    This is a very good straight to the point tutorial! However I spotted a weird artifact appearing in the very center of the TMP asset (at the position of the TMP [T] gizmo). You can sort of see it at 1:41 at the top left corner of the 'm' in "some". When inspected closely it's a square mesh wobbling with the text, it doesn't matter if there's any text near the area, just appears at the very center.
    Sometimes this artifact disappears when I add a few more characters and sometimes it itself shows as a blob of characters... Any ideas what might cause this? Thanks!

    • @Madalaski
      @Madalaski  2 роки тому +1

      Hmmm, if I think I noticed this problem a couple months later but I can't remember the exact suction. I believe it has something to do with a character being added to overall text but the new character didn't have it's new vertices set, creating an artifact. Might be worth to create a buffer zone of some kind. One of my later videos has code for my Code Animator software in the description. I believe that uses a better algorithm if you want to check that out.

    • @skipperkippz4564
      @skipperkippz4564 2 роки тому +1

      If you're still encountering this issue, I've just found a solution, so even if you've fixed it on your own I'll leave it here for people who come after ^u^
      It looks like this artifact is where "extra" characters are stored. Instead of creating and destroying a bunch of meshes, the engine just creates a mesh when needed and stores it very very small when it's not being used. However when messing with the vertices, you manually make these "extra" stored meshes visible by giving them scale. Accessing the vertices on a character-by-character basis instead of vertex-by-vertex basis should fix the issue, since you aren't accessing the extra stored meshes this way.

  • @BigManJD
    @BigManJD 4 роки тому +2

    U should livestream the creation of ur game and then edit them into devlogs 🤷‍♂️

    • @Madalaski
      @Madalaski  4 роки тому +2

      Sadly I do not have the internet connection for streaming at the moment ;(
      Plus that would spoil the surprises... ;)

    • @haemogoblin7006
      @haemogoblin7006 4 роки тому +1

      @@Madalaski understandable, have a nice day

  • @gabaguiarp
    @gabaguiarp Рік тому

    Great video, straight to the point!
    But I didn't get the part at 1:38...
    I am using a non-UI, world space TextMeshPro component and the mesh gets all deformed. Obviously there is no canvas renderer for that, but there's also no "SetMesh" method. What am I supposed to assign in order for the modified mesh to work with world space text?

    • @muhammadaqil6467
      @muhammadaqil6467 3 місяці тому

      i'm having this issue, did you figure it out?

  • @ChazzBurger
    @ChazzBurger 2 роки тому +1

    ok so these text effects are AMAZING!
    there is one niche problem that i am having though,
    when the text is scrolling through with the typewriter effect,
    the wobble and colour effects seem to jitter a bit which is very strang.
    Looking at the code i really cannot find out why this is happening.
    Just asking here in case anyone has had this issue before and found a solution.
    Thanks!

    • @Madalaski
      @Madalaski  2 роки тому

      Hmmm not sure what's going on here. I'd recommend looking at the Code Animator code that I put on the Obra Dinn video. I think that used a better algorithm for text scrolling.

    • @MsRedNebulaPlays
      @MsRedNebulaPlays 2 місяці тому

      I know this is a very late reply, but just in case anyone else runs into a similar problem, this was my solution. My typewriter effect was done with a coroutine and updated the text using TMPro's maxVisibleCharacters, and added each new character using WaitForSeconds. When that happened, the text wobble effect glitched out, so I think it was happening out of step with Update.
      So, instead of putting the code from this tutorial in Update, I moved it to its own separate method and then called it every time my coroutine fired (in addition to calling it normally from Update). No more glitching!

  • @Coffee_Bubblee
    @Coffee_Bubblee 2 роки тому

    where do i even put the script? its not as a component to the text layer... I am too nooby to get this help

  • @neozoid7009
    @neozoid7009 2 роки тому

    Awesome

  • @ojtaylor2249
    @ojtaylor2249 4 роки тому +1

    I couldn't find it on Unity Store??

    • @Madalaski
      @Madalaski  4 роки тому +4

      Find what? TextMeshPro? It's in Packages, already comes with Unity.

  • @itookaonabookanyway7385
    @itookaonabookanyway7385 2 роки тому

    is there a way to do this using GPU computing via shaders or custom properties?
    it feels like using a C# script for a mesh, every vert for every frame would be horrible for CPU calculations

    • @Madalaski
      @Madalaski  2 роки тому

      Possibly! But you'd definitely have to feed in some kind of information about which characters are being affected when :)

  • @srbiscuit
    @srbiscuit 2 роки тому

    text just move 1 frame and stops, script is the same as yours

  • @SpydrXIII
    @SpydrXIII 2 роки тому

    murican grades are 1-12.

  • @thatabyssegg8507
    @thatabyssegg8507 Рік тому

    "Just copy it, you don't need to understand this"
    Uh... I thought the whole point of tutorials was to make me understand at least most of the stuff that was mentioned .-.

  • @lucasmontec
    @lucasmontec Рік тому

    COOL TEXT EFFECTS IN UNITY: How to smash your GPU and explode your draw calls.

  • @justinruane3796
    @justinruane3796 3 роки тому

    it works perfectly on a single scene but when i tried to apply the WordWobble script to another text on a different scene it keeps giving me a null reference exception error on this line
    textMesh.ForceMeshUpdate();
    it would be very helpful if you could help me understand and solve this!

    • @Madalaski
      @Madalaski  3 роки тому

      Are you sure the text ur applying the script to is using TextMeshPro?

    • @justinruane3796
      @justinruane3796 3 роки тому +1

      @@Madalaski yes, i am
      Here is the code if you like:
      using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      using TMPro;
      public class WordWobble : MonoBehaviour
      {
      TMP_Text textMesh;
      Mesh mesh;
      Vector3[] vertices;
      List wordIndexes;
      List wordLengths;
      public Gradient rainbow;
      // Start is called before the first frame update
      void Start()
      {
      textMesh = GetComponent();
      wordIndexes = new List { 0 };
      wordLengths = new List();
      string s = textMesh.text;
      for (int index = s.IndexOf(' '); index > -1; index = s.IndexOf(' ', index + 1))
      {
      wordLengths.Add(index - wordIndexes[wordIndexes.Count - 1]);
      wordIndexes.Add(index + 1);
      }
      wordLengths.Add(s.Length - wordIndexes[wordIndexes.Count - 1]);
      }
      // Update is called once per frame
      void Update()
      {
      textMesh.ForceMeshUpdate();
      mesh = textMesh.mesh;
      vertices = mesh.vertices;
      Color[] colors = mesh.colors;
      for (int w = 0; w < wordIndexes.Count; w++)
      {
      int wordIndex = wordIndexes[w];
      Vector3 offset = Wobble(Time.time + w);
      for (int i = 0; i < wordLengths[w]; i++)
      {
      TMP_CharacterInfo c = textMesh.textInfo.characterInfo[wordIndex + i];
      int index = c.vertexIndex;
      colors[index] = rainbow.Evaluate(Mathf.Repeat(Time.time + vertices[index].x * 0.001f, 1f));
      colors[index + 1] = rainbow.Evaluate(Mathf.Repeat(Time.time + vertices[index + 1].x * 0.001f, 1f));
      colors[index + 2] = rainbow.Evaluate(Mathf.Repeat(Time.time + vertices[index + 2].x * 0.001f, 1f));
      colors[index + 3] = rainbow.Evaluate(Mathf.Repeat(Time.time + vertices[index + 3].x * 0.001f, 1f));
      vertices[index] += offset;
      vertices[index + 1] += offset;
      vertices[index + 2] += offset;
      vertices[index + 3] += offset;
      }
      }
      mesh.vertices = vertices;
      mesh.colors = colors;
      textMesh.canvasRenderer.SetMesh(mesh);
      }
      Vector2 Wobble(float time)
      {
      return new Vector2(Mathf.Sin(time * 3.3f), Mathf.Cos(time * 2.5f));
      }
      }

    • @justinruane3796
      @justinruane3796 3 роки тому

      On my first scene where i used the script on a text mesh pro element, i dont get any errors but when i push the button on my screen to switch to the next scene, the
      text element where i applied the same wordwobble script says that on line 38 object referecne is not set to an instance of an object. I also got the same error for line 26
      Line 38:
      textMesh.ForceMeshUpdate();
      Line 26:
      string s = textMesh.text;

    • @justinruane3796
      @justinruane3796 3 роки тому

      @@Madalaski Yes, i am. i just finished doing a test run of the same situation on a new empty unity project and im not getting that problem anymore. However its still very strange and confusing that i was getting this error in the first place. Im very new to unity so its pretty rough having to deal with these errors. If you have any idea what might be causing it, feel free to let me know as i would still like to find out the reason behind it and what that error even means.

    • @Madalaski
      @Madalaski  3 роки тому +1

      @@justinruane3796 Hey there, sorry I've been swamped today. Your code looks fine and your errors just mean that the textMesh component is somehow being accessed before it's set or doesn't exist in the first place. So, if you're certain that you're using a textmeshpro text object and not a regular text UI element, then the only other explanation is that Update() is being called before Start() when you load the scene. Super weird but easily fixable. Either make textMesh variable public and drag the TMP_Text component into it's field in the inspector or wrap the whole of the Update() function with a if (textMesh != null) { } statement.