top of page

Language Learning Superheroes

A mobile app (Android & iOS) that I developed for a client. The app is a companion app to a language learning book (English to Spanish) for medical professionals.

-

Every aspect of the app was developed by myself, with the exception of the artwork.

LLS_Preview 02.jpg

Features and Challenges

Google AdMob Integration

The app features ads that are serviced through Google AdMob. Although there's not much to say about this, it is worth mentioning that this project required working with third-party APIs.

Anchor 1
Working With 3000+ Vocabulary Terms

One of the biggest challenges during development was dealing with a large number of vocabulary terms that were constantly being altered and edited. It was imperative that the vocab terms in the app matched the latest edits of the book, so to accommodate this I developed a solution to automate this process.

My solution was to put the vocab terms into a spread sheet using Google Sheets, and then download the file from within Unity. I shared this spread sheet with the client and instructed him to share it with anyone else who was making edits. Now in Unity, I would simply click a button to check for updates. This would send out a web request to download the spread sheet as a CSV file, parse through the result, and populate the data into a scriptable object that housed all of the vocab terms. Easy!

Not only was my project now always up to date with the latest edits of the book (with no effort on my end), but the client now also had a centralized location for the master vocab list that could be accessed by anyone working on the book, which benefited the client greatly.

Anchor 2
Custom Tweening Solution

Although there are already a lot of excellent tweening solutions that I could have chosen to use for this project, I instead opted to create my own custom solution. As this project was for a client and I was unsure if anyone else would be brought on to work on the code base, it seemed logical to minimize third-party dependencies as much as possible.

The tweening solution that I developed is based on coroutines. A 'TweenManager' game object is lazy instantiated and placed into the DontDestroyOnLoad scene. The TweenManager is responsible for keeping track of all active tweens, as well as stopping and starting tweens to make sure that they don't overlap or interfere with one another in any way. I then wrote several extension methods, that made use of the TweenManager, to easily tween a number of different values such as positions, rotations, scales, colors, etc...

Anchor 3
Custom Save System w/ AES Encryption

To keep track of the user's progress when using the app, a system needed to be implemented to save data locally. To accommodate this I created a save system that writes save data as a JSON file. The save file could then either be encrypted or left alone. Leaving the file unencrypted was useful during testing to make sure that data was being saved and loaded properly, whereas, encrypting the file was useful in the final build to make sure that users couldn't easily alter the contents of the save file.

Anchor 4
Creation Of 'Round Rect' UI Component

Many mobile applications use a minimalist art style to convey a simple, sleek, and user friendly look. This was something that I wanted to capture in this app as well.

 

One way that I achieved this was by creating a custom UI component that I called 'RoundRect'. At it's core RoundRect is a UI image component, however, it makes use of a special shader and additional tweakable properties. The shader uses a SDF approach to create a rectangle with rounded corners. This approach has the benefit of producing results with no aliasing artifacts. Additionally, the shader handles per-corner roundness, outlines, horizontal/vertical gradients, and drop shadows. The high performance and flexibility of this component made it's use ubiquitous throughout the app.

Anchor 5
Creation Of 'Pooled Scrollable List' UI Component

Another challenge that I encountered during development occurred within the flashcards section of the app. The flashcards section needed to allow users to search and scroll through all of the vocabulary terms. Since there were over 3000 vocab terms in total, simply placing them all onto a ScrollRect component wouldn't be possible due to the performance cost.

My solution was to create a system that would pool and reuse flashcard prefabs when they were no longer visible. While scrolling down, the top most flashcard would be repositioned to the bottom of the list and updated with the appropriate vocab term for that index within the list. The inverse would happen when scrolling up. This allowed me to use only 10 flashcards on the ScrollRect component, even though the list itself could potentially contain thousands of vocab words.

Anchor 6
bottom of page