The following custom Action allows you to specify an exact position to move a character to. To use it, create a new C# file named ActionCharPathFindVector, and follow the instructions in the "Custom Actions" chapter of the Manual.
ActionCharPathFindVector.cs:
using UnityEngine; using System.Collections; using System.Collections.Generic; #if UNITY_EDITOR using UnityEditor; #endif namespace AC { [System.Serializable] public class ActionCharPathFindVector : Action { public Vector3 moveToVector; public int moveToVectorParameterID = -1; public int charToMoveParameterID = -1; public int charToMoveID = 0; public bool isPlayer; public Char charToMove; public PathSpeed speed; public bool pathFind = true; public bool doFloat = false; public bool doTimeLimit; public int maxTimeParameterID = -1; public float maxTime = 10f; [SerializeField] private OnReachTimeLimit onReachTimeLimit = OnReachTimeLimit.TeleportToDestination; private enum OnReachTimeLimit { TeleportToDestination, StopMoving }; private float currentTimer; public ActionCharPathFindVector () { this.isDisplayed = true; category = ActionCategory.Character; title = "Move to vector"; description = "Moves a character to a given vector."; } public override void AssignValues (List<ActionParameter> parameters) { charToMove = AssignFile <Char> (parameters, charToMoveParameterID, charToMoveID, charToMove); moveToVector = AssignVector3 (parameters, moveToVectorParameterID, moveToVector); if (isPlayer) { charToMove = KickStarter.player; } maxTime = AssignFloat (parameters, maxTimeParameterID, maxTime); } override public float Run () { if (!isRunning) { isRunning = true; if (charToMove) { Paths path = charToMove.GetComponent <Paths>(); if (path == null) { ACDebug.LogWarning ("Cannot move a character with no Paths component"); } else { if (charToMove is NPC) { NPC npcToMove = (NPC) charToMove; npcToMove.StopFollowing (); } path.pathType = AC_PathType.ForwardOnly; path.pathSpeed = speed; path.affectY = true; Vector3[] pointArray; Vector3 targetPosition = moveToVector; if (SceneSettings.ActInScreenSpace ()) { targetPosition = AdvGame.GetScreenNavMesh (targetPosition); } float distance = Vector3.Distance (targetPosition, charToMove.transform.position); if (distance <= KickStarter.settingsManager.destinationAccuracy) { isRunning = false; return 0f; } if (pathFind && KickStarter.navigationManager) { pointArray = KickStarter.navigationManager.navigationEngine.GetPointsArray (charToMove.transform.position, targetPosition, charToMove); } else { List<Vector3> pointList = new List<Vector3>(); pointList.Add (targetPosition); pointArray = pointList.ToArray (); } if (speed == PathSpeed.Walk) { charToMove.MoveAlongPoints (pointArray, false, pathFind); } else { charToMove.MoveAlongPoints (pointArray, true, pathFind); } if (charToMove.GetPath ()) { if (!pathFind && doFloat) { charToMove.GetPath ().affectY = true; } else { charToMove.GetPath ().affectY = false; } } if (willWait) { currentTimer = maxTime; return defaultPauseTime; } } } return 0f; } else { if (charToMove.GetPath () == null) { isRunning = false; return 0f; } else { if (doTimeLimit) { currentTimer -= Time.deltaTime; if (currentTimer <= 0) { switch (onReachTimeLimit) { case OnReachTimeLimit.StopMoving: charToMove.EndPath (); break; case OnReachTimeLimit.TeleportToDestination: Skip (); break; } isRunning = false; return 0f; } } return (defaultPauseTime); } } } override public void Skip () { if (charToMove) { charToMove.EndPath (); if (charToMove is NPC) { NPC npcToMove = (NPC) charToMove; npcToMove.StopFollowing (); } Vector3[] pointArray; Vector3 targetPosition = moveToVector; if (SceneSettings.ActInScreenSpace ()) { targetPosition = AdvGame.GetScreenNavMesh (targetPosition); } if (pathFind && KickStarter.navigationManager) { pointArray = KickStarter.navigationManager.navigationEngine.GetPointsArray (charToMove.transform.position, targetPosition); KickStarter.navigationManager.navigationEngine.ResetHoles (KickStarter.sceneSettings.navMesh); } else { List<Vector3> pointList = new List<Vector3>(); pointList.Add (targetPosition); pointArray = pointList.ToArray (); } int i = pointArray.Length-1; if (i>0) { charToMove.SetLookDirection (pointArray[i] - pointArray[i-1], true); } else { charToMove.SetLookDirection (pointArray[i] - charToMove.transform.position, true); } charToMove.Teleport (pointArray [i]); } } #if UNITY_EDITOR override public void ShowGUI (List<ActionParameter> parameters) { isPlayer = EditorGUILayout.Toggle ("Is Player?", isPlayer); if (!isPlayer) { charToMoveParameterID = Action.ChooseParameterGUI ("Character to move:", parameters, charToMoveParameterID, ParameterType.GameObject); if (charToMoveParameterID >= 0) { charToMoveID = 0; charToMove = null; } else { charToMove = (Char) EditorGUILayout.ObjectField ("Character to move:", charToMove, typeof (Char), true); charToMoveID = FieldToID <Char> (charToMove, charToMoveID); charToMove = IDToField <Char> (charToMove, charToMoveID, false); } } moveToVectorParameterID = Action.ChooseParameterGUI ("Position to reach:", parameters, moveToVectorParameterID, ParameterType.Vector3); if (moveToVectorParameterID < 0) { moveToVector = EditorGUILayout.Vector3Field ("Position to reach:", moveToVector); } speed = (PathSpeed) EditorGUILayout.EnumPopup ("Move speed:" , speed); pathFind = EditorGUILayout.Toggle ("Pathfind?", pathFind); if (!pathFind) { doFloat = EditorGUILayout.Toggle ("Ignore gravity?", doFloat); } willWait = EditorGUILayout.Toggle ("Wait until finish?", willWait); if (willWait) { EditorGUILayout.Space (); doTimeLimit = EditorGUILayout.Toggle ("Enforce time limit?", doTimeLimit); if (doTimeLimit) { maxTimeParameterID = Action.ChooseParameterGUI ("Time limit (s):", parameters, maxTimeParameterID, ParameterType.Float); if (maxTimeParameterID < 0) { maxTime = EditorGUILayout.FloatField ("Time limit (s):", maxTime); } onReachTimeLimit = (OnReachTimeLimit) EditorGUILayout.EnumPopup ("On reach time limit:", onReachTimeLimit); } } AfterRunningOption (); } override public void AssignConstantIDs (bool saveScriptsToo, bool fromAssetFile) { if (saveScriptsToo) { if (!isPlayer && charToMove != null && charToMove.GetComponent <NPC>()) { AddSaveScript <RememberNPC> (charToMove); } } if (!isPlayer) { AssignConstantID <Char> (charToMove, charToMoveID, charToMoveParameterID); } } #endif } }