diff --git a/package-lock.json b/package-lock.json
index 61e6e706e4977110a209c031c786254d4574ff0e..abb6c6a7c7063a8be9d46308db519f92c8b85eba 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12633,9 +12633,8 @@
       }
     },
     "three-pathfinding": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/three-pathfinding/-/three-pathfinding-0.7.0.tgz",
-      "integrity": "sha512-UwWvzgio1UFe81n5jKHNzB4B+AG3wfZ54OKp7bTb1MHuC3cy6RTtr0dbbiPQQoqxzr+DRArR2DUwQSEknw5+nw=="
+      "version": "github:mozillareality/three-pathfinding#0531aaecca181b4be6d6de71003db39034e354f5",
+      "from": "github:mozillareality/three-pathfinding#hubs/master"
     },
     "three-to-cannon": {
       "version": "1.3.0",
diff --git a/package.json b/package.json
index 105c0753a6fecb1a2fe075a1e97ae66aa07adfdf..656738f02a27dc0a51a249959981993881c9a811 100644
--- a/package.json
+++ b/package.json
@@ -56,7 +56,7 @@
     "screenfull": "^3.3.2",
     "super-hands": "github:mozillareality/aframe-super-hands-component#feature/drawing",
     "three": "github:mozillareality/three.js#8b1886c384371c3e6305b757d1db7577c5201a9b",
-    "three-pathfinding": "^0.7.0",
+    "three-pathfinding": "github:mozillareality/three-pathfinding#hubs/master",
     "three-to-cannon": "1.3.0",
     "uuid": "^3.2.1",
     "webrtc-adapter": "^6.0.2"
diff --git a/src/components/character-controller.js b/src/components/character-controller.js
index dba2bc4dd66a7595dbef20ca85a8ead162f35bcf..36c7c641fc58cc205278b635abef13fc4af8d699 100644
--- a/src/components/character-controller.js
+++ b/src/components/character-controller.js
@@ -171,44 +171,30 @@ AFRAME.registerComponent("character-controller", {
     console.warn("character-controller", msg);
   },
 
-  setPositionOnNavMesh: function(start, end, object3D) {
-    const pathfinder = this.el.sceneEl.systems.nav.pathfinder;
-    const zone = this.navZone;
-    if (zone in pathfinder.zones) {
-      if (this.navGroup == null) {
-        this.navGroup = pathfinder.getGroup(zone, end);
-      }
-      this.navNode = this.navNode || pathfinder.getClosestNode(end, zone, this.navGroup, true);
-      if (this.navNode) {
-        try {
-          this.navNode = pathfinder.clampStep(start, end, this.navNode, zone, this.navGroup, object3D.position);
-        } catch (e) {
-          // clampStep failed for whatever reason. Don't stop the main loop.
-          if (this._withinWarningLimit) this._warnWithWarningLimit(`setPositionOnNavMesh: clampStep failed. ${e}`);
-        }
-      } else {
-        if (this._withinWarningLimit) this._warnWithWarningLimit("setPositionOnNavMesh: navNode is null.");
-      }
+  _updateNavState: function(pos, forceUpdate) {
+    const { pathfinder } = this.el.sceneEl.systems.nav;
+    if (this.navGroup === null || forceUpdate) {
+      this.navGroup = pathfinder.getGroup(this.navZone, pos, true);
+    }
+    if (this.navNode === null || forceUpdate) {
+      this.navNode =
+        pathfinder.getClosestNode(pos, this.navZone, this.navGroup, true) ||
+        pathfinder.getClosestNode(pos, this.navZone, this.navGroup);
     }
   },
 
+  setPositionOnNavMesh: function(start, end, object3D) {
+    const { pathfinder } = this.el.sceneEl.systems.nav;
+    if (!(this.navZone in pathfinder.zones)) return;
+    this._updateNavState(end);
+    this.navNode = pathfinder.clampStep(start, end, this.navNode, this.navZone, this.navGroup, object3D.position);
+  },
+
   resetPositionOnNavMesh: function(position, navPosition, object3D) {
-    const pathfinder = this.el.sceneEl.systems.nav.pathfinder;
-    const zone = this.navZone;
-    if (zone in pathfinder.zones) {
-      this.navGroup = pathfinder.getGroup(zone, position);
-      this.navNode = pathfinder.getClosestNode(navPosition, zone, this.navGroup, true) || this.navNode;
-      if (this.navNode) {
-        try {
-          this.navNode = pathfinder.clampStep(position, position, this.navNode, zone, this.navGroup, object3D.position);
-        } catch (e) {
-          // clampStep failed for whatever reason. Don't stop the main loop.
-          if (this._withinWarningLimit) this._warnWithWarningLimit(`resetPositionOnNavMesh: clampStep failed. ${e}`);
-        }
-      } else {
-        if (this._withinWarningLimit) this._warnWithWarningLimit("resetPositionOnNavMesh: navNode is null.");
-      }
-    }
+    const { pathfinder } = this.el.sceneEl.systems.nav;
+    if (!(this.navZone in pathfinder.zones)) return;
+    this._updateNavState(navPosition, true);
+    object3D.position.copy(navPosition);
   },
 
   updateVelocity: function(dt) {