Movement and input
Units move by intent: something calls MoveTo(destination), the unit asks a path provider for waypoints, follows them, and writes its position through a movement executor. Nothing else in the package touches transform.position.
flowchart LR
In[Right-click input] -->|MoveTo| M[VtTopDownClickToMove]
AI[Chase / roam / abilities] -->|MoveTo| M
M -->|RequestPath| P["IVtPathProvider<br/>(yours, optional)"]
M -->|Move| E["IVtMovementExecutor<br/>local or client-auth"]
Setup
Add these to the unit prefab:
| Component | Role |
|---|---|
VtTopDownClickToMove |
Path following, acceleration, rotation, gravity. Adds a local executor and a CharacterController if none exist. |
VtNavMeshPathProvider |
Pathfinding on a baked NavMesh. Optional but recommended. |
VtTopDownClickInput |
Player only. Right-click on ground moves, on a hostile attacks, on an item or NPC walks over and interacts. |
VtAbilityHotkeys |
Player only. Casts abilities from keys, see below. |
VtTopDownAnimatorBinding |
Optional. Writes the measured speed to an Animator float parameter. |
Monsters use the same mover and provider; roaming and chasing go through them, see AI roaming.
VtTopDownClickInput needs the click raycast layers set and a Ground Layer for the fallback move surface. Turn on Spawn Move Marker for a click marker.
Speed comes from the unit definition’s Move Speed, scaled by the move-speed stat, so slows and hastes are ordinary buffs.
Runtime
var move = unit.GetComponent<VtTopDownClickToMove>();
move.MoveTo(point, onArrived: () => Interact());
move.MoveTo(point, acceptPartialPath: true);
move.Stop();
move.Teleport(point);
move.IsMoving;
move.CurrentPath;
move.OnArrived += () => { };
A new move order interrupts a cast in progress.
Pathfinding
Add Vantage → Movement → VtNavMeshPathProvider next to VtTopDownClickToMove and bake a NavMesh with Unity’s AI Navigation package: put a NavMeshSurface component on your level and press Bake. That is the whole setup. The provider snaps the start and the destination onto the mesh and follows the corners.
| Setting | Meaning |
|---|---|
| Sample Radius | How far off the mesh a start or destination may be and still snap onto it. |
| Area Mask | Which NavMesh areas this unit may walk. |
| Fallback To Straight Line | When the unit is on no mesh at all, walk straight and warn once, so an unbaked scene still plays. |
Without any provider, units walk in a straight line, which is fine for prototypes and flat arenas.
Other backends plug in through the IVtPathProvider interface: one method that calls back exactly once with the waypoints, or with null when there is no path. Put the component next to VtTopDownClickToMove and it is picked up automatically.
A* Pathfinding Project (needs a Seeker on the unit):
using System;
using System.Collections.Generic;
using Pathfinding;
using UnityEngine;
[RequireComponent(typeof(Seeker))]
public sealed class AstarPathProvider : MonoBehaviour, IVtPathProvider
{
private Seeker seeker;
private void Awake() => seeker = GetComponent<Seeker>();
public void RequestPath(Vector3 from, Vector3 to, Action<List<Vector3>> onComplete)
{
seeker.StartPath(from, to, p => onComplete(p == null || p.error ? null : p.vectorPath));
}
}
Casting from keys
Add Vantage → Movement → VtAbilityHotkeys to the player prefab and fill the slots: a key and an ability each. Keys 1 to 5 are bound by default. A press casts at once, at whatever the ability’s targeting mode implies:
| Targeting mode | Cast at |
|---|---|
| Self | The caster. |
| Single target | The unit under the cursor, otherwise the current target. |
| Ground point | The point under the cursor on the ground layers. |
var hotkeys = player.GetComponent<VtAbilityHotkeys>();
hotkeys.Assign(0, fireball);
hotkeys.Bind(0, Key.Q);
hotkeys.Press(0); // UI button
hotkeys.OnCastFailed += (ability, reason) => Toast(reason);
hotkeys.Slots; // for drawing a hotbar
Cooldowns for the hotbar come from VtUnitAbilities.GetCooldownFraction. Replace CursorRay for a gamepad cursor.
Movement feel
Acceleration, turn rate, waypoint reach distance, stuck recovery and gravity are global values on the tuning asset.
Executors
VtLocalMovementExecutor moves the CharacterController directly and is what single-player uses. VtClientAuthMovementExecutor does the same but only when this instance owns the unit, which is what a co-op host build needs. Swap the component on the prefab; nothing that calls MoveTo changes. See Multiplayer.
Targeting and chasing
VtCombatEngagement holds the current target, chases into range and faces it. Abilities and the auto-attack use it, and your AI can too:
var engagement = unit.GetComponent<VtCombatEngagement>();
engagement.SetTarget(enemy);
engagement.HasLiveTarget;
engagement.IsInRange(5f);
engagement.ClearTarget();
engagement.OnTargetChanged += target => { };
Interacting with the world
Right-clicking anything that implements IVtPickable walks the unit over and calls it. World items, quest givers and crafting stations implement it. Implement it yourself for levers, doors and shops.