Last year about this time I was doing some motion & comp work for a pair of cinematics for a big ol' video game. One of my shots involved having these indicators moving across a screen with a hexagonal tile grid, and the art director wanted the indicators to snap from one tile to the next, giving it a much choppier, digital feel.

It took a while (longer than I'd care to admit, but alas) to get this expression put together. I won't claim that it's the best (or even most efficient) way, but if anyone has any suggestions on how I can optimize it please let me know!

The Code

var L = thisComp.layer("Control");
var P = thisComp.layer("Motion Path - Hex");

var xPos = P.transform.position[0];
var yPos = P.transform.position[1];

var cSize = L.effect("Cell Size")("Slider");
var xOffset = L.effect("X Offset")("Slider");
var yOffset = L.effect("Y Offset")("Slider");

// Convert size value into distance values between cells
var cWidth = cSize * .75;
var cHeight = cSize * 13 / 15;

// Find new X and Y positions
var yNew = yPos - yPos % cHeight + cHeight / 2;
var xNew = xPos - (xPos % cWidth) + (((yNew - cHeight / 2).toFixed(2) / cHeight).toFixed(2) % 1) * (cWidth / 2);

// Check for even/odd column, adjust properly
if (!(xNew % (cWidth * 2) == 0)) {
  yNew += cHeight / 2;
}

// Implement offset
[xNew + xOffset, yNew + yOffset]

The Explanation

One thing to note is that this is using YY_HexTex by Andrew Yang to generate the hexagonal grid. As such, it's adapted specifically for it though it's fairly easy to swap it out for a premade grid.

The way this works is by looking at the current position, snapping the values to the centre of a grid, then checking to see whether you're in an even or odd column and adjusting the y-value again accordingly. At the very end, we add in the user-controlled offset so that our layer lines up with the grid properly.

Another thing to notice is that line 17 invokes two uses of toFixed(). If they're not included, AE has trouble working with some really long decimals and the results tend to go a bit awry. This looks messy in the code, but it's the only fix I could find.

The Application

To the left, you can see that without snapping, our snazzy little man will just spin around the path-- that's what  we'd expect.To the right, Mr. Tieman will still follow the path, although now it'll keep its movement constrained to the hex grid. Stay classy, Tieman.

This can be used for all sorts of FUI/interface work, as hex grids seem to be ubiquitous these days. Or, you know, for your latest and greatest Settlers of Catan fan vid, if you're into that sort of thing.

If you want to use this on a 3d layer, it'll take some rejigging to get it to put together, but it should prove an adequate challenge for anyone familiar with expression work.

Download link below. Once you have it open, play with the "Control" layer sliders to explore different results. You'll have to adjust the offset values to fit the grid properly.


Download here