protected override Vector3 ClampToNavmesh(Vector3 position, out bool positionChanged) { if (constrainInsideGraph) { cachedNNConstraint.tags = seeker.traversableTags; cachedNNConstraint.graphMask = seeker.graphMask; cachedNNConstraint.distanceXZ = true; var clampedPosition = PathFindHelper.GetNearest(position, cachedNNConstraint).position; // We cannot simply check for equality because some precision may be lost // if any coordinate transformations are used. var difference = movementPlane.ToPlane(clampedPosition - position.ToPFV3()); float sqrDifference = difference.sqrMagnitude; if (sqrDifference > 0.001f * 0.001f) { // The agent was outside the navmesh. Remove that component of the velocity // so that the velocity only goes along the direction of the wall, not into it velocity2D -= difference.ToUnityV2() * Vector2.Dot(difference.ToUnityV2(), velocity2D) / sqrDifference; // Make sure the RVO system knows that there was a collision here // Otherwise other agents may think this agent continued // to move forwards and avoidance quality may suffer if (rvoController != null && rvoController.enabled) { rvoController.SetCollisionNormal(difference.ToUnityV2()); } positionChanged = true; // Return the new position, but ignore any changes in the y coordinate from the ClampToNavmesh method as the y coordinates in the navmesh are rarely very accurate return(position + movementPlane.ToWorld(difference).ToUnityV3()); } } positionChanged = false; return(position); }
/** Simulates rotating the agent towards the specified direction and returns the new rotation. * \param direction Direction in world space to rotate towards. * \param maxDegrees Maximum number of degrees to rotate this frame. * * Note that this only calculates a new rotation, it does not change the actual rotation of the agent. * Useful when you are handling movement externally using #FinalizeMovement but you want to use the built-in rotation code. * * \see #rotationIn2D */ public Quaternion SimulateRotationTowards(Vector3 direction, float maxDegrees) { return(SimulateRotationTowards(movementPlane.ToPlane(direction.ToPFV3()).ToUnityV2(), maxDegrees)); }