Handwriting

This post will be in English because, unlike other posts, this one may contain useful thingy’s.

At the end of the post we will be able to replicate the effect seen on a movie. For this tutorial I will use schoolbell font.

Step 1. Export the font.

After importing the *.ttf file into Unity, set the correct size (usually really big, 150px or more) and create the editable copy, as shown in the following screenshot. If you can not be bothered with tracing that many letters for tutorial purpose, limit your options to only upper or lower case. I did that.

createEditableCopy

Step 2. Trace the letters in gimp/photoshop

Open the exported file in gimp, and then trace the files with gradient ranging from red to black. Do it as if you were writing those letters by hand. The more red parts will be rendered first, the more black ones second. In the end you should end up with something like this:

Schoolbell_handwriting

Step 3. Part of the shader

First of all, we need to find the shader unity uses for UI fonts. After getting the build-in shaders from unity website, we see that UI/Unlit/Text shader falls back on UI/Default Font shader which then falls back on UI/Default one. Let’s just copy-paste this one and add the possibility to multiply the alpha by a value from an external map.

Step 4. Keeping track of the current letter

After the following steps, we are able to get this:

handwriting1

The letters write themselves just fine, but there is no way yet to tell the shader which letter should be animated, and which one is already written.

My first idea was to pass to the shader the coordinates of the current letter in world space view. That proven unsuccessful, as the letters may overlap.

Another idea is to use color variable associated with each vertex of the final text mesh. Normally, each vertex gets the same color as the color of the text. The code below colors the vertices of a text mesh accordingly, so that only the letter with index lettersShown is colored.

Step 5. Final modifications of the shader.

Step 6. Animation coroutine

Uszy – wrzucanie własnych obrazków

Wczoraj wrzuciłam film pokazujący jaki efekt chciałam osiągnąć. Dzisiaj rozbicie tego efektu na części pierwsze.

  1. Wybór i załadowanie obrazka z dysku
  2. Dopasowanie zawartości obrazka do wymaganej wielkości
  3. Przycięcie obrazka, zachowanie przyciętego wyniku w odpowiedniej teksturze.
  4. Nałożenie nowej tekstury na Sprite, przy jednoczesnym zachowaniu wymiarów rzeczonego Sprite’a
  5. Upewnienie się, że dostępna tekstura będzie cały czas owalna, tak żeby ładnie mieściła sie w ramce

Wybór i załadowanie obrazka z dysku

Nad tym punktem nie zamierzam sie rozwodzić. W wypadku systemu Windows można po prostu użyć OpenFileDialog, w wypadku pozostałych platform na pewno znajdziecie jakieś wtyczki. Ja użyłam tej: Unified Android API, niekoniecznie dlatego że jest dobra, ale była pierwsza z brzegu i darmowa, a ja jestem dośc leniwa, nie chciało mi się pisać samodzielnie. Mozna też spróbowac skleić to samemu, nie powinno być trudne. Potencjalne linki TU i TU.

Dopasowanie zawartości obrazka do wymaganej wielkości

Krok 1 – ułożenie elementu w scenie

scroller_setup
Obrazek który będziemy przycinać, jest ładowany do elementu ChosenImage. Element ImageCropSpot powinien mieć odpowiedni stosunek szerokości do wysokości, bo do niego będziemy przycinać.

Krok 2 – czy oba palce znajdują sie na obrazku?

Krok 3 – zwiększanie/zmniejszanie rozmiaru obrazka

Podzieliłam to na dwie klasy – jedna z nich upewnia się że ScrollRect w którym znajduje się przeskalowywany obrazek jest wyłączony podczas skalowania. Jesli nie byłby on wyłączony, obrazek przeskakiwał by podczas skalowania, bo ScrollRect próbował by go przesunąć. Druga klasa po prostu zwieksza/zmniejsza obrazek, mając na uwadze aby jego wielkość w pikselach nie była mniejsza od zadanej (w szczególności nie mniejsza niż obrazek do którego będziemy przycinać).
Kolejna ważna rzecz: pivot. Na początku pivot obrazka jest ustawiony na (0.5, 0.5), czyli na sam jego środek. W związku z tym, podczas zwiększania/zmniejszania, obrazek będzie sie skalował „od środka”, co może wyglądać trochę nienaturalnie dla użytkownika. Zazwyczaj oczekuje się, ze podczas skalowania elementem niezmiennym jest element znajdujący się równo pośrodku palców które „rozciągają” obrazek.

scroller_pivot

Klasy sa bardzo długie i bardzo nudne, więc zamiast wklejać je w całości, poniżej linki do githuba.

https://github.com/ania1234/FencingEars/blob/master/Assets/Scripts/ZoomHelper.cs
https://github.com/ania1234/FencingEars/blob/master/Assets/Scripts/ZoomableImage.cs

Przycięcie obrazka, zachowanie przyciętego wyniku w odpowiedniej teksturze.

Nałożenie nowej tekstury na Sprite, przy jednoczesnym zachowaniu wymiarów rzeczonego Sprite’a

Po wykonaniu powyższych kroków, w zmiennej statycznej TextureManager.portraitTexture znajduje sie przycięty obrazek. Jego stosunek jego wymiarów jest taki jak w oryginalnym obrazku, ale jego wymiary w pikselach moga się różnić. Ponieważ chcemy zachować oryginalne wymiary wyświetlonego sprite’a, należy zmienić rozdzielczość dla nowego Sprite’a, czyli pomanipulować przy pixelsPerUnit.

Upewnienie się, że dostępna tekstura będzie cały czas owalna, tak żeby ładnie mieściła sie w ramce

Postanowiłam trochę zmodyfikować SpriteShader wbudowany w unity. Dodatkowo przyjmuje teraz teksturę _MaskTex. Nieprzezroczyste miejsca na teksturze maski są renderowane jako przezroczyste. Zastosowane rozwiązanie działa wtedy, keidy _MainTex i _MaskTex mają taki sam stosunek długości boków. Kod poniżej:

Uszy – podejście drugie. Wrzucanie własnych obrazków.

Po roku wracam do projektu który próbowałam nieśmiało wykonać rok temu. Tym raqzem zamiast na skończonym projekcie skupię się na poszczególnych elementach, moze wystarczy mi motywacji na kolejne 4-5 wpisów. Będzie to pewien sukces. Poniżej film z tematem pierwszego wpisu, a jutro wpis o tym jak takowy efekt osiągnąć.