Skip to main content

Grid-Based Movement System

MCE uses a tile-based grid movement system built on Unity's Tilemap. The player and NPCs move one tile at a time on a discrete grid, with collision detection, terrain effects, and cross-map transitions handled by the grid system.

How a step is resolved

The grid in play

The player is always on exactly one tile. There is no half-step and no sub-tile position, and that is what makes encounters, collision and cross-map transitions decidable rather than approximate.

Core Components​

GridController​

The GridController is the per-scene manager for the tile grid. It sits on the same GameObject as Unity's Grid (it requires one) and:

  • Finds the scene's Tilemaps and answers tile queries across them, from the highest sort order to the lowest.
  • Reads each tile's movement type from the project's TileData asset (see Custom Tile Types).
  • Tracks the characters and actors registered on the grid.
  • Holds the scene's SceneInfo (see below).
  • Answers collision queries: can a character move to this tile, from this tile?

Each map scene has one GridController on its grid root.

MCECharacterController​

The MCECharacterController handles movement for any character (player, NPC or a monster) on the grid:

  • Grid-snapped movement: Characters move exactly one tile per step.
  • 4-directional movement: Up, Down, Left, Right. No diagonal movement.
  • Sprite rendering: Updates the sprite direction and walk animation.
  • Collision checking: Queries the GridController before each move.
  • Movement speed: Speed, in seconds per tile (0.25 by default).

PlayerCharacter​

The PlayerCharacter adds player-specific features on top of the controller:

  • Input handling (keyboard and gamepad).
  • Interaction triggers (pressing the action button while facing an NPC/object).
  • Wild encounter handling, repel steps and the step counter (GlobalGameData.StepsTaken, which also drives egg cycles and friendship).
  • Running, biking and swimming.
  • Follower monster coordination and the emote hotkeys.

GlobalGridManager​

The GlobalGridManager handles cross-map navigation:

  • Keeps the list of loaded grids and finds the grid that has a tile at a world position, so a character can walk from one map into its neighbour.
  • Loads the neighbours of the current map additively, and the neighbours of those neighbours (two hops deep), so crossing an intermediate map does not unload the one you came from.
  • Hands over the player when a character crosses from one grid to another.

Tile Types​

Every tile asset has a movement type (TileType), assigned in the TileData asset:

TileTypeDescription
NonExistentThe tile has no data; treated as void
WalkableNormal ground
NonWalkableSolid obstacle (walls, trees, rocks)
JumpableA ledge: crossed by jumping, in one direction
BridgeBridge surface, layered above what is under it
BridgeEntranceTransition tile between ground and bridge
WaterWater that needs swimming to cross
WaterfallVertical water that can be climbed
SlipperyIce: the character slides until it hits an obstacle
WalkableNotBikableWalkable on foot but not on a bicycle

On top of the type, tile behaviours (components on the tile's prefab) add logic: EncounterTile marks a wild encounter zone, OneWayJumpableTile sets the direction of a ledge, ForceCharacterToKeepMoving makes conveyor belts and currents, TallGrass, LadderUp, WaterfallEdge, WhirlwindInDirection and more. They are all described in Custom Tile Types.

Setting Up a Map​

Step 1: Create the Tilemap Structure​

MCE maps use a standard Unity Tilemap hierarchy:

Grid (Grid + GridController)
└── Ground (Tilemap, TilemapRenderer, sorting order 0)
└── GroundOverlay (Tilemap, TilemapRenderer, sorting order 1)
└── Above ... (more Tilemaps as needed)
└── Actors (NPC GameObjects)

There is no separate collision tilemap to paint: what blocks movement is the TileType of the tiles you paint.

Step 2: Paint the Map​

Use the Map Editor overlay, or Unity's Tile Palette (Window > 2D > Tile Palette), to paint your map:

  1. Ground layer: Base terrain (paths, grass, dirt, water edges).
  2. Overlay layers: Decorations on top of ground (flowers, rocks, shadows) and what draws over the player (tree canopies).
  3. Encounter tiles: Tiles whose prefab carries an EncounterTile where wild monsters appear.

Step 3: Add the GridController​

  1. Select the Grid root GameObject.
  2. Add the GridController component.
  3. The controller receives the project's TileData asset through dependency injection; make sure every tile you painted is registered there with the right TileType (the asset's Populate and CheckInvalid buttons help). A tile that is not registered is treated as walkable and logs a warning.

Step 4: Configure SceneInfo​

Each map scene needs a SceneInfo component pointing to a SceneInfoAsset (create it with New Scene Info in the Hub's Database tab). Assign the component to the GridController's Scene Info field. The asset holds:

FieldDescription
SceneThe scene this info describes
Localizable Name KeyDisplay name of the location (shown in the header)
Neighbours / Neighbour OffsetsThe maps that connect to this one and where they sit, in tiles (seamless crossings)
Background MusicMusic for this map
Is Affected By Sky, Default Weather, Allowed WeathersDay/night light and weather
Can Open Storage Here, Can Fly From Here, Can Teleport From Here, Can Escape Rope From Here, Can Fish HereWhat the player may do here
Is Dungeon, Is DarkA dungeon map uses Cave encounters on every tile
Region, TagsThe region and the scene tags used by game logic (for example "Cave", "Town", "Route")
Encounters, Battle Scenarios Per Encounter, Own Encounter ChancesWild encounters of the map: see Wild Encounters

Special Terrain​

Bridges​

Bridges let a character walk over tiles that would otherwise be impassable (like water):

  1. Use a tilemap layer with a higher sorting order for the bridge.
  2. Give the bridge tiles the Bridge type and the tiles where you step onto it BridgeEntrance.
  3. The character walks on the bridge layer when it steps onto it.

Bridge logic handles the Z-ordering -- the character renders above the water but below bridge railings (OverBridgeBodySortOrder).

Slippery Tiles (Ice)​

On ice tiles, the character slides in the direction it is moving until it hits a wall or a non-ice tile:

  1. Give the ice tiles the Slippery type.
  2. The MCECharacterController overrides input and continues the movement direction.
  3. Add walls or obstacles to create ice puzzle layouts.

Ledges​

Ledges are one-way tiles -- the character can jump down but not climb back up:

  1. Give the tile the Jumpable type and add the OneWayJumpableTile behaviour to its prefab.
  2. Set its Jump Direction.
  3. A hop animation plays when the character crosses the ledge.

Waterfalls​

Waterfalls can be climbed with the appropriate ability:

  1. Give the waterfall tiles the Waterfall type (the edge can use WaterfallEdge).
  2. When the player faces the waterfall and uses the climbing ability, the character ascends.

Cross-Map Transitions​

Seamless Connections​

For maps that connect directly (Route 1 continues into Route 2 at the north edge), list each map in the other's Neighbours with the tile Neighbour Offsets that place it. The GlobalGridManager loads the neighbours additively and the character simply walks from one grid into the other: when the current grid has no tile at the target position, the manager looks for a loaded grid that does. A tile of a neighbour that is a wall (NonWalkable) or void (NonExistent) still blocks the step.

Warps (Doors, Caves, Teleports)​

To move the player to another place:

  1. Place a TriggerActor on the door or entrance tile (a TriggerActor does not block movement and runs a graph when the player steps in).
  2. In its CommandGraph add a TeleportPlayer node with the destination as a scene location (the target SceneInfoAsset and the tile). When online, the server validates the teleport first.
  3. Optionally add OpenDoor, FadeScreenToBlack and sounds around it to dress the transition.

Imported maps get their warps placed for you by the importer's scene integration.

Player Movement Configuration​

Movement speed is the Speed field of the character, in seconds per tile (0.25 by default, i.e. four tiles a second). The state of the character scales the time per tile:

StateMultiplier of the time per tile
Walking1
Running (IsRunning)0.33
Biking (IsBiking)0.15
Swimming (IsSwimming)0.66
Jumpingthe hop plays at 1.5x of the step time

The step counter (GlobalGameData.StepsTaken) advances with every step and drives egg cycles and friendship ticks.

Monster Followers​

MCE supports a follower system where the first monster in the player's party walks behind them in the overworld:

  • The MonsterFollowerController manages the follower's position and sprite.
  • The follower stays one tile behind the player and catches up behind it after cutscenes.
  • Follower sprites are configured per species and form in the MonsterEntry (the WorldIdleSprite* and WorldWalkingSprite* fields).
  • The player can interact with the follower (face it and press the action button) to see a reaction; an imported game can bring its own talk table, and the follower can show emotion balloons.
Follower Sprites

If a monster species does not have an overworld follower sprite assigned, the follower will not appear. Create follower spritesheets as 4-direction walk cycle sheets.

Best Practices​

  1. Keep tile types consistent. Register every painted tile in TileData and use the same type for the same kind of terrain.
  2. Test warp connections both ways. Make sure you can go from A to B and back from B to A.
  3. Use scene tags for logic. Rather than hardcoding map names, tag maps as "Cave", "Water", "Forest", etc.
  4. Optimize large maps. Very large tilemaps can impact performance. Consider splitting into multiple connected scenes with Neighbours.
  5. Test with gamepad. Grid movement should feel responsive on both keyboard and controller.