Blender Simulation of Liquid Filling a Cocktail Glass

I finally resolved a problem that has plagued me for years, which is simulating liquid filling in a cocktail glass. It seems like this could be solved with a simple scale in the upward direction in Unity, but it’s a lot more complex. My cocktail glass model has two meshes, one for the glass which remains static and another for the fluid which increases in size as the glass is filled. The fluid mesh is an upsidedown cone with a flattened top. Simply scaling the fluid mesh will result in the fluid mesh not correctly filling the glass.

Simple scale of entire fluid mesh gives incorrect fill of cocktail glass
Simple scale of entire fluid mesh gives incorrect fill of cocktail glass

When I created the original fluid mesh in Blender , I believe I used the boolean difference modifier, but it’s been years since I created it so I could have possibly used some other method. For the animation, I used an armature in Blender with two bones. A bottom bone for controlling the ring of vertexes at the bottom of the fluid mesh and a top bone for controlling the ring of vertexes at the top of the mesh.

The new 2.80 version of Blender has significant changes for weight painting. I created the following infographic to show the process I use for weight painting a mesh. For my fuild mesh, I set full wieght of the top vertexes to the top bone, and the full weight of the bottom vertexes to the bottom bone.

Weight Painting in Blender 2.80

To solve the liquid filling problem, the bottom set of vertexes must remain unchanged, while the top vertexes move upward and scale outward. The fluid mesh is modeled with the glass filled. Therefore, in Blender the default pose is the last frame in the animation. I used 60 frames for this animation, so I set the keyframe for the 60th frame with the default pose. It is important to set the keying mode to location, rotation, and scale. In most of my games, I only set the key mode to location and rotation, since game objects are rarely ever scaled.

To create the filling effect, in Animation mode I set the frame in the timeline to the first frame. Then I select the top bone and scale it inward (on the X and Y axes) so that it matches the same diameter as the bottom of the glass (and same diameter as the ring of bottom vertexes). Then I translate the top bone downward, until it exactly overlaps with the bottom ring of vertexes. Then I add a keyframe for the first frame. Pressing play will show the simulated liquid starting from the bottom of the glass and filling to the rim of the glass.

Correct cocktail glass fill animation using two armature bones
Correct cocktail glass fill animation using two armature bones

I plan to use this new liquid fill animation technique to update Bartender Game in the near future.


Unity Version Tool

The latest updates and documentation can be found on the Unity Build Tool wiki page.

One of the biggest problems with having 59 Unity projects is keeping them all up to date.  I knew many of my Unity projects were out of date and needed to be updated to the latest version of Unity, but I didn’t have a good method for detecting which ones.  I had previously developed build and upload scripts in Ruby to create Windows BAT files to compile a project for Windows, MacOS and Linux and upload those builds to Itchio using Butler.  However, those BAT files could not make Unity WebGL builds.

The Unity Version Tool that I developed solves these problems.  It was developed in Ruby using the GTK+3 graphical libraries.

Unity Version Tool

  • Pressing Scan Projects will check all subfolders in the specified project directory for Unity projects.
  • If a project does not match the current version of Unity or PlayMaker, then the project will be highlighted in red.  Default version values can be set in the unity_version.config file.  The version number of the project is checked from ProjectSettings/ProjectVersion.txt and files ending with the .csproj extension.
  • Pressing Update Version will attempt to read the current version of Unity installed on the system (<User Profile>/AppData/Local/Unity/Editor/Editor.log) and store it in the unity_version.config file.  The PlayMaker version information is read from Assets/PlayMaker/Editor/PlayMakerWelcomeWindow.cs.
  • Individual projects can be selected by checking the boxes next to the project names, or all projects can be selected or deselected using the checkbox in the header row.
  • Builds for the selected projects can be compiled for Windows, MacOS, Linux, or WebGL.
  • WebGL builds require a script to be generated from the included template, which is embedded into the project for compilation, since there is not a Unity command line option for making WebGL builds.  It uses the “-executeMethod” command line parameter to execute project script.
  • All builds for a project can be deleted by pressing Clear build folder.
  • By default, the Unity editor will start on compilation.  I may add “-batchmode” as an option in the future to compile without starting the Unity editor, but I’ve noticed issues lately with using the “-batchmode” Unity parameter.  If a project is compiled and it is not using the latest version, then Unity will prompt to update the project.  Therefore, it is advisable to update the projects (which are highlighted in red) by opening them before selecting the compile option.
  • Note that while updating the Unity project to the latest version, there may be multiple .csproj files that still return an old version of Unity.  I’ve found that the .csproj files (such as Assembly-CSharp.csproj, Assembly-CSharp-Editor.csproj, and <project>.csproj) can be safely deleted in most cases, and Unity should create new versions of those files the next time a script is accessed in the Unity editor.  Hopefully, I will add an option to remove old .csproj files.
  • After updating a Unity project, it may be necessary to make a change (such as moving a GameObject in the Hierarchy and moving it back) in order for the ProjectSettings/ProjectVersion.txt to be updated.  I don’t know if there are any drawbacks to manually updating the version number in that file, so I wouldn’t advise doing it.

Using this tool, it is possible to compile multiple project for a selected platform at once.  This is a process that had previously taken me hours or days for WebGL projects, since each project would need to be opened, updated, platform setting changed, and then compiled.  It still takes a long time, but at least now I can kick it off before going to bed and just let it run.

Download the Unity Version Tool  (Ruby and GTK+3 required to be installed on system, which is not included)

Thoughts on First Game Booth at Knoxville Gaming Convention

One weekend ago, members of Knoxville Game Design (Dylan, Joe, Jacob, and myself) had a booth at the Knoxville Gaming Convention.  This was a part of the larger CreepyCon convention at the World’s Fair Exhibition Hall.

I really wasn’t sure what to expect, since we have never done a display at a convention this large.  However, we had some experience with setting up game demos at McKay Retro Game Night, Makerpalooza, Open Streets Knoxville, and Emory Place Block Party.


We had a 20′ x 10′ booth, so I wasn’t sure how much could fit in that space.  I actually simulated the booth space in Unity with simple Blender models the night before to get an idea of how much space we would have.  The biggest estimation error that I made was that we would only have two tables instead of four.  We actually had plenty of booth space, but we were limited by table space.

I had a 18″ x 24″ glossy sign made at Staples with the Knoxville Game Design logo.  I also bought a portable easel there to hold it.  If I had to do it again, I probably wouldn’t have chosen the glossy lamination.  It reflects a lot of light which sometimes makes the text on the sign hard to see.  Also, I saved money by not getting it mounted on a hard surface.  I could always just cut out a piece of cardboard and tape it to the back of the sign next time to keep it from looking droopy while sitting on the easel.  Overall, I spent less than $50 total on the sign and easel, which is much less in price and less of a hassle than the rollup signs which go for around $200.

However, I thought the top of the booth was a little plain.  We had one small printed black and white sign provided by the convention.  I had to duct tape it to the poll since I didn’t have any string.  However, next time I would like to get big banner to stretch across the top.

On one table, we had one television, one monitor, and a laptop.  The television was connected to a Mac laptop by HDMI, and played games through the Itch client.  I made sure to download most of my gamepad playable games at home before arriving, since we did not have reliable Internet access there.  The convention did offer (slow) WiFi at a price, but we decided not to sign up for that.  The other monitor was also connected to my old Mac laptop by HDMI as well.  There really wasn’t any issues with the display, but I did have to remember to mirror the displays on the laptops which were sitting behind the monitors.  The biggest hassle was getting the gamepads to work.  The XBox controller does not work with a Mac without third party software being downloaded and installed.  Fortunately, I already had this setup on the old laptop.  On the new laptop, I just used a PS4 controller connected by mini USB.  However, the button mappings were wrong, so I had to manually configure the buttons on the Input configuration when the Unity game started.  Plus, I had to watch out for some actions that were mapped to multiple buttons, such as Jump and Submit triggering on the same or different buttons.  The third display on the table was just a laptop that showed screenshots from games.

On the other table, we had one television connected to an XBox One, one monitor connected to an Intel compute stick, and handouts.  Dylan gave me instructions for setting up the Intel compute stick, and I got everything running except for the game, which later he figured out was due to me using the wrong power adapter.  Apparently the one that I connected didn’t give the Intel compute stick enough power to run the game.  We also setup a tray for another monitor running on Jacob’s laptop.  I stacked up some of the storage boxes for a monitor connected to my portable Raspberry Pi arcade box, which ran a simple Honey Bear game that I created in Scratch.  I thought it was a good example for how beginners can learn to program.  The only problem was that the Raspberry Pi would go to sleep about every 10 minutes, so I had to periodically tap the joystick.  The XBox One would also go to standby, but I was eventually able to dig around in the menus to find the settings to keep it from doing that.  The obvious monitor idle setting wasn’t enough, and there was another app idle setting that had to be changed.

I tried to come prepared by bringing scotch tape, scissors, sharpie markers, a pen, and other supplies.  One of the televisions was new, so one thing I didn’t anticipate was needing a phillips head screwdriver to put the legs on the bottom.  Luckily, I asked around and someone let me borrow one.  I also let other booths borrow supplies like the scotch tape.  I also brought sheets to cover up our displays at the end of the day.

While setting up, the power unexpectedly went out.  I contacted the event coordinators and they traced it down to the plugs being loose on the main power switch.  The booth had an outlet on a plug with three plugins.  I believe we had four power strips and two extension cords, so we had power coverage for the entire booth.

We had many games for people to play in our booth.  Kitty’s Adventure seemed to be popular with kids.  The biggest problem was that I needed to manually restart the game after someone had finished playing, since the level difficulty increased with bigger mazes as the game progressed.  New players should start back at the beginning.  I’ve heard others talk about having a “convention mode”, which offers a smaller sampling of the game with the ability to easily reset.  Dylan had his Knox Runner game on display, which was our only multiplayer game.  He also had three kindle tablets with his Retrofuture, Shifty Shapes, and One Card Hero games.  You can read more about his Kindle Fire setup on his site.  Joe from DoubleSquare had a laptop showing off screenshots and videos of his games, as well as a playable Khufu’s Delivery Service on a tablet.  Jacob had Lost Signal, a game that he created for Ludum Dare, on display and was playable by keyboard.  I also had Turn Back the Clocks 4, which people seemed to like once they understood the rules.  Amish Brothers was on a monitor on the first day, but I changed it to Easter Egg Hunt on the second day, since I think is a more polished game.

One thing I thought was helpful was putting printed names of the games on top of each of the monitors, because that would have been the first thing that people would have asked.  Plus, it lets the other spectators see the name of the games being played, without us having to tell them.

The most popular handout was the brochure.  I liked them because it had all of our regular members, links to their websites, and some of their games listed.  It was one thing that I could give to somebody that had all of our information.  The individual business cards were nice, but may be a little too much when we have four separate developers.  My stickers were also somewhat popular, but it seems really hard to get rid of the magnets.  I’m not sure if people just don’t understand what they are or if the magnets are just inconvenient to carry.  Most people have space on their refrigerators for magnets, so I thought they would be more popular.

The biggest misconception that most people seemed to have was that our booth was for one company or game studio.  We had to keep telling people that we were each individual developers, and the booth was for our community group.  Most people seemed to be supportive, and I heard “did you make these games yourself” a few times.  I think the biggest thing we were going for with our booth was the awareness of our group, and there are game developers in Knoxville.  People seem to be supportive of things that are locally created.  Another issue that some people had was not knowing that they were allowed to play the games.  The controllers seemed to be placed openly, and I don’t know if making a sign that says “feel free to play our games” would help at all.

We met quite a few people at our booth.  Zane Everett from the Atlanta IGDA came up from Georgia to see the Knoxville Gaming Convention.  He recommended that we check out SeigeCon in Atlanta in a few months, which sounds like a mini GDC in the Southeast.  I also believe some of the members of KnoxDevs stopped by since I posted about it on their Slack group.

The overall area for the gaming part of the convention was relatively small, but we were close to the main stage which did bring lots of foot traffic when events started and ended.  This was supposed to be a preview for a future gaming convention, so we are definitely looking forward to doing it again.  Aside from us, LevelUp games had retro games to play, Token Game Taven had arcades and pinball machines, ExtraLife had a live stream setup, and there was laser tag information.  There was also a few cornhole setups to play or purchase, and large jenga blocks that frequently crashed which was unsettling at first, but I seemed to habituate to it after a while.

We were all fans of Wild Bill’s root beer, which gave unlimited root beer refills if you paid for one of the collector mugs.  There was about ten different kinds of root beer to choose from, including original, vanilla, grape, orange, and six shooter.  I will admit that it was a lot more sugar that I am usually accustomed to consuming for two days.

Shutdown was fairly hectic, since we were ready to get out of there after being there for 15 hours over two days.  We were able to get everything boxed up fairly quickly, but carrying everything out was exhausting.  They offered to cart everything out for us, but we would have been one of the last ones to leave.  Unfortunately, I wasn’t allowed to park next to the entrance, but I did eventually manage to get a spot a little closer with my vendor badge.