{"id":394564,"date":"2024-06-29T11:42:17","date_gmt":"2024-06-29T11:42:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=394564"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=394564","title":{"rendered":"<span>\u0418\u0437 Unity \u0432 Unigine. NavMesh<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041a\u0440\u0430\u0442\u043a\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0446\u0435\u043d\u0430 \u0432 <strong>Unity<\/strong>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u043a\u0443\u0431, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0438\u0433\u0440\u043e\u043a\u043e\u043c \u043c\u044b\u0448\u043a\u043e\u0439, \u0438 \u0441\u0438\u043d\u044f\u044f \u043a\u0430\u043f\u0441\u0443\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u043a\u0443\u0431\u043e\u043c. \u041e\u043d\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0431\u0435\u043b\u043e\u043c\u0443 \u043f\u043b\u0435\u0439\u043d\u0443 \u0432\u043e\u043a\u0440\u0443\u0433 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fdf\/4f1\/07e\/fdf4f107e6110954634a9add04754f82.png\" alt=\"\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unity\" title=\"\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unity\" width=\"1098\" height=\"821\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fdf\/4f1\/07e\/fdf4f107e6110954634a9add04754f82.png\"\/><figcaption>\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unity<\/figcaption><\/figure>\n<p>\u0411\u044b\u043b\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u043a\u0430. \u041d\u0430 \u0437\u0435\u043b\u0435\u043d\u043e\u043c \u043a\u0443\u0431\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b <strong>NavMeshAgent<\/strong> \u0438 <strong>PlayerNavigation<\/strong>. \u0421\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 <strong>NavMeshAgent<\/strong> \u0438 <strong>TargetNavigation<\/strong>. \u041d\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u043a\u0443\u0431\u0430\u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>NavMeshObstacle<\/strong>.  <\/p>\n<pre><code class=\"cs\">public class PlayerNavigation : MonoBehaviour { private NavMeshAgent _agent = null; private Camera _camera = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); _camera = Camera.main; }  private void Update() { if ( Input.GetMouseButtonDown( 0 ) ) { Ray ray = _camera.ScreenPointToRay( Input.mousePosition ); if ( Physics.Raycast( ray, out RaycastHit hit ) ) _agent.SetDestination( hit.point ); } } }<\/code><\/pre>\n<pre><code class=\"cs\">public class TargetNavigation : MonoBehaviour { [SerializeField] Transform _target = null; private NavMeshAgent _agent = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); }  private void Update() { _agent.SetDestination( _target.position ); } }<\/code><\/pre>\n<pre><code class=\"cs\">public class VisualPath : MonoBehaviour { private LineRenderer _lineRenderer = null; private NavMeshAgent _agent = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); _lineRenderer = GetComponent&lt;LineRenderer>(); }  private void LateUpdate() { if ( _agent.hasPath ) { _lineRenderer.positionCount = _agent.path.corners.Length; _lineRenderer.SetPositions( _agent.path.corners ); } } }<\/code><\/pre>\n<h3>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 Unigine<\/h3>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438.<\/p>\n<p>\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0432 Unigine \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u043c\u0435\u0448\u0435\u043c (<strong>Navigation Mesh<\/strong>) \u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u043c (<strong>Navigation Sector<\/strong>), \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0432 2D \u0438 3D \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 (\u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 2D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Z <strong>\u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/strong>).<\/p>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448 &#8212; \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430 \u043c\u0435\u0448\u0430. <strong>\u0412\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c<\/strong>, \u0447\u0442\u043e \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 <strong>\u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430<\/strong>. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448 \u0438\u043b\u0438 \u0441\u0435\u043a\u0442\u043e\u0440 \u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u043f\u0443\u0442\u0438 <strong>\u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/strong>, \u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 <strong>\u0442\u043e\u043b\u044c\u043a\u043e 2D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430<\/strong>. \u0421\u0430\u043c \u043c\u0435\u0448 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 3D \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/6c3\/27a\/ad5\/6c327aad542f46011fa0c47e65d20b28.png\" alt=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448\" title=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448\" width=\"777\" height=\"777\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/6c3\/27a\/ad5\/6c327aad542f46011fa0c47e65d20b28.png\"\/><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/navigation\/navigation_mesh\/?rlang=cpp&amp;autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Navigation Mesh<\/a><\/p>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440 &#8212; \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430. \u041e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 2D \u0438 3D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432. \u0427\u0442\u043e\u0431\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0431\u044b\u043b \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0434\u0438\u0443\u0441 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0447\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043c\u043e\u0433\u043b\u0430 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4f5\/d1c\/da4\/4f5d1cda427342b171ac6d5f2b9cf50a.png\" alt=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440\" title=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440\" width=\"745\" height=\"623\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4f5\/d1c\/da4\/4f5d1cda427342b171ac6d5f2b9cf50a.png\"\/><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/navigation\/navigation_sector\/?rlang=cpp&amp;autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Navigation Sector<\/a><\/p>\n<p>Obstacle (\u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f) \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0433\u0438\u0431\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0435 \u043a\u0443\u0431\u0430, \u0441\u0444\u0435\u0440\u044b \u0438\u043b\u0438 \u043a\u0430\u043f\u0441\u0443\u043b\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/941\/12f\/526\/94112f526454b688f87f1f610f4ef9a4.png\" alt=\"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430\" title=\"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430\" width=\"405\" height=\"382\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/941\/12f\/526\/94112f526454b688f87f1f610f4ef9a4.png\"\/><figcaption>\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/obstacle\/?autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Obstacle<\/a><\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043c\u0438\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438  <\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0438\u0440 \u0438 \u043e\u0431\u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439 <strong>Unity<\/strong>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d36\/872\/bb4\/d36872bb4a76fd9b48a645678a035de8.png\" alt=\"\u041e\u0431\u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043c\u0438\u0440 \u0432 Unigine\" title=\"\u041e\u0431\u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043c\u0438\u0440 \u0432 Unigine\" width=\"858\" height=\"423\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d36\/872\/bb4\/d36872bb4a76fd9b48a645678a035de8.png\"\/><figcaption>\u041e\u0431\u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043c\u0438\u0440 \u0432 Unigine<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0442\u043e\u0440 <strong>Create -> Navigation -> Navigation Sector<\/strong>. \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c \u0435\u0433\u043e \u0432\u044b\u0448\u0435 \u043f\u043b\u0435\u0439\u043d\u0430 \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044f <strong>Size<\/strong> \u0432 \u043e\u043a\u043d\u0435 <strong>Parameters<\/strong>, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0432 \u0444\u043e\u0440\u043c\u0435 \u0443\u0440\u043e\u0432\u043d\u044f.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/963\/323\/08f\/96332308fcf155f8cf7bc016d0cf0b92.png\" alt=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440\" title=\"\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440\" width=\"1364\" height=\"397\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/963\/323\/08f\/96332308fcf155f8cf7bc016d0cf0b92.png\"\/><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u0440\u0430\u0441\u043d\u044b\u0435 \u043a\u0443\u0431\u044b, \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f <strong>Create -> Navigation -> Obstacle Box<\/strong>.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/77a\/375\/ff2\/77a375ff2d116ede1ab283c263403b86.png\" alt=\"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\" title=\"\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f\" width=\"1374\" height=\"425\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/77a\/375\/ff2\/77a375ff2d116ede1ab283c263403b86.png\"\/><figcaption>\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f<\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0437\u043e\u043d\u044b \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439, \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c <strong>\u0445\u0435\u043b\u043f\u0435\u0440\u044b<\/strong>.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/590\/600\/07d\/59060007d2378e19dd8cbd6e2ec5910e.jpg\" alt=\"\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439\" title=\"\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439\" width=\"247\" height=\"980\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/590\/600\/07d\/59060007d2378e19dd8cbd6e2ec5910e.jpg\" data-blurred=\"true\"\/><figcaption>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/93d\/a2c\/d17\/93da2cd1757285e4ec042b10b4aeaff0.png\" alt=\"\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0438\u0440\" title=\"\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0438\u0440\" width=\"1338\" height=\"373\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/93d\/a2c\/d17\/93da2cd1757285e4ec042b10b4aeaff0.png\"\/><figcaption>\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0438\u0440<\/figcaption><\/figure>\n<h3>\u041a\u043b\u0430\u0441\u0441 PathRoute  <\/h3>\n<p><strong>PathRoute<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u043f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043c\u0435\u0436\u0434\u0443 A \u0438 B \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0432\u0443\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432: <strong>Create2D(vec3 A, vec3 B)<\/strong> \u0438 <strong>Create3D(vec3 A, vec3 B)<\/strong>.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0432 \u043c\u0430\u0441\u043a\u0438 \u0434\u043b\u044f \u0441\u0435\u043a\u0442\u043e\u0440\u0430 (\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430) \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ca9\/fa9\/b76\/ca9fa9b76813e30737dc5f3ed7d62896.png\" alt=\"\u041c\u0430\u0441\u043a\u0430 \u0434\u043b\u044f \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430\" title=\"\u041c\u0430\u0441\u043a\u0430 \u0434\u043b\u044f \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430\" width=\"426\" height=\"391\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ca9\/fa9\/b76\/ca9fa9b76813e30737dc5f3ed7d62896.png\"\/><figcaption>\u041c\u0430\u0441\u043a\u0430 \u0434\u043b\u044f \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430<\/figcaption><\/figure>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0440\u0430\u0434\u0438\u0443\u0441 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443. \u0415\u0441\u043b\u0438 \u0441\u0435\u043a\u0442\u043e\u0440 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435, \u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 <strong>\u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0438\u0437 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438<\/strong>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1ad\/301\/257\/1ad3012579eb29b643e850b9a70a2e84.png\" alt=\"\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432\" title=\"\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432\" width=\"1378\" height=\"639\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1ad\/301\/257\/1ad3012579eb29b643e850b9a70a2e84.png\"\/><figcaption>\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/bd2\/0c3\/479\/bd20c3479e9e99ff47a0cfa17288c9cb.png\" alt=\"\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432\" title=\"\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432\" width=\"1032\" height=\"565\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bd2\/0c3\/479\/bd20c3479e9e99ff47a0cfa17288c9cb.png\"\/><figcaption>\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432<\/figcaption><\/figure>\n<h3>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442  <\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430. \u0417\u0430\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430: \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u043f\u043e\u0432\u043e\u0440\u043e\u0442, \u0440\u0430\u0434\u0438\u0443\u0441, \u0432\u044b\u0441\u043e\u0442\u0443, \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438 \u043c\u0430\u0441\u043a\u0438. \u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <strong>\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430<\/strong> \u0438\u043b\u0438 <strong>\u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430<\/strong>!<\/p>\n<pre><code class=\"cs\">public class NavigationAgent : Component { [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Speed = 4; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u043e\u0434\u044b \u043f\u043e \u043f\u0443\u0442\u0438 [ParameterSlider( Max = 60, Min = 0, Group = \"Agent\" )] public float RotationSpeed = 25; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u043d\u043e\u0434\u044b [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Radius = 0.4f; \/\/\u0420\u0430\u0434\u0438\u0443\u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Height = 0.5f; \/\/\u0412\u044b\u0441\u043e\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float StopDistance = 0.3f; \/\/\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterMask( Group = \"Parameter Mask\" )] public int NavigationMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u043c\u0435\u0448\u0430 [ParameterMask( Group = \"Parameter Mask\" )] public int ObstacleMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u043f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 }<\/code><\/pre>\n<p>\u0417\u0430\u0434\u0430\u0434\u0438\u043c \u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0445 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u0430.\u00a0<\/p>\n<pre><code class=\"cs\">private bool _isRecalculate; \/\/\u0421\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private vec3 _pointDirection; \/\/\u0422\u043e\u0447\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private PathRoute _route; \/\/\u041a\u043b\u0430\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <strong>InitRoute<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f\u043c \u043a\u043b\u0430\u0441\u0441\u0430 <strong>PathRoute<\/strong> \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0438\u0437\u0432\u043d\u0435. <\/p>\n<pre><code class=\"cs\">private void InitRoute() {     _route.NavigationMask = NavigationMask;     _route.ObstacleMask = ObstacleMask;     _route.Radius = Radius;     _route.Height = Height; }<\/code><\/pre>\n<p>\u0418 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Init<\/strong> \u0438 <strong>Update<\/strong>.  <\/p>\n<pre><code class=\"cs\">private void Init() {     _route = new PathRoute();     InitRoute(); }  private void Update() {     InitRoute(); } <\/code><\/pre>\n<p>\u0414\u0430\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <strong>RenderVisualizer<\/strong> \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong>. \u0421\u0430\u043c\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0432 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 Init \u201c<strong>Visualizer.Enabled = true;<\/strong>\u201d \u0438\u043b\u0438 \u0432\u0432\u0435\u0434\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u201c<strong>show_visualizer 1<\/strong>\u201d.<\/p>\n<pre><code class=\"cs\">private void RenderVisualizer() { \/\/\u0420\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u043b\u0438\u043d\u0434\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u044b\u0441\u043e\u0442\u044b \u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 Visualizer.RenderCylinder( Radius, Height, node.WorldTransform, vec4.RED );      \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0443\u0442\u044c if ( _route.IsReached )     _route.RenderVisualizer( vec4.RED ); }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 <strong>SetDirection<\/strong>. \u041f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<pre><code class=\"cs\">public void SetDirection( in vec3 point, in bool recalculate = true ) { _pointDirection = point; _isRecalculate = recalculate;  _route.Create2D( node.WorldPosition, point ); }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0430\u0433\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <strong>MoveDirection<\/strong>. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e.<\/p>\n<pre><code class=\"cs\">private void MoveDirection() { if ( _route.IsReached ) { if ( _route.Distance &lt;= StopDistance ) return;         \/\/\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435     } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u0435\u0449\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d.<\/p>\n<pre><code class=\"cs\">vec3 direction = _route.GetPoint( 1 ) - _route.GetPoint( 0 ); if ( direction.Length2 > MathLib.EPSILON ) {     \/\/\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435   }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u041c\u0435\u0442\u043e\u0434\u043e\u043c <strong>MathLib.SetTo<\/strong> \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0438 \u0438\u0437 \u043d\u0435\u0435 <strong>quat<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <strong>MathLib.Slerp<\/strong> \u0431\u0443\u0434\u0435\u043c \u043f\u043b\u0430\u0432\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u043e\u0434\u044b \u0430\u0433\u0435\u043d\u0442\u0430.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u043e\u0434\u044b \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f quat directionRotation = new quat( MathLib.SetTo( vec3.ZERO, direction.Normalized, vec3.UP, MathLib.AXIS.Y ) ); quat newRotation = MathLib.Slerp( node.GetWorldRotation(), directionRotation, Game.IFps * RotationSpeed ); node.SetWorldRotation( newRotation );<\/code><\/pre>\n<p>\u0417\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u043e\u0434\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432\u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0431\u044f.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u043e\u0434\u044b node.Translate( vec3.FORWARD * Game.IFps * Speed );<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043d\u0443\u0436\u0435\u043d \u043b\u0438 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 if ( _isRecalculate )     _route.Create2D( node.WorldPosition, _pointDirection );<\/code><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong> \u043c\u0435\u0436\u0434\u0443 <strong>InitRoute<\/strong> \u0438 <strong>RenderVisualizer<\/strong>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u043a \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443 \u0438 \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/599\/9bc\/0d1\/5999bc0d1248b4b918b6e2a8cdac8b4a.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 Navigation Agent\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 Navigation Agent\" width=\"413\" height=\"552\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/599\/9bc\/0d1\/5999bc0d1248b4b918b6e2a8cdac8b4a.png\"\/><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 Navigation Agent<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <strong>TargetNavigation<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u043c \u043a\u0443\u0431\u043e\u043c. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u0432 <strong>NavigationAgent<\/strong> \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0448\u0430 \u0442\u043e\u0447\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>SetDirection<\/strong> \u0432 <strong>PostUpdate<\/strong>.<\/p>\n<pre><code class=\"cs\">public class TargetNavigation : Component { [ShowInEditor] Node _target = null;  private NavigationAgent _agent = null;  private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); }  private void PostUpdate() { _agent.SetDirection( _target.WorldPosition, false ); } }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 <strong>PlayerNavigation<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u0438.<\/p>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0442\u0440\u0438 \u043f\u043e\u043b\u044f: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442, \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0438 \u043a\u0430\u043c\u0435\u0440\u0430.<\/p>\n<pre><code class=\"cs\">public class PlayerNavigation : Component { private NavigationAgent _agent = null; private WorldIntersection _intersection = new WorldIntersection(); private Player _playerCamera = null; }<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Init<\/strong> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u043a\u0430\u043c\u0435\u0440\u0443. \u0422\u0430\u043a\u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u043c.  <\/p>\n<pre><code class=\"cs\">private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); _playerCamera = Game.Player;  Input.MouseHandle = Input.MOUSE_HANDLE.USER; }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043b\u0443\u0447, \u0432 \u0442\u043e\u0447\u043a\u0435 \u0441\u043e\u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443.  <\/p>\n<pre><code class=\"cs\">private void MoveNavigation() { ivec2 mousePosition = Input.MousePosition; vec3 start = _playerCamera.WorldPosition; vec3 end = start + _playerCamera.GetDirectionFromMainWindow( mousePosition.x, mousePosition.y ) * 100f;  Object intersectionObject = World.GetIntersection( start, end, 1, _intersection ); if ( intersectionObject ) _agent.SetDirection( _intersection.Point ); }<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>MoveNavigation<\/strong> \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u041b\u041a\u041c.  <\/p>\n<pre><code class=\"cs\">private void Update() { if ( Input.IsMouseButtonDown( Input.MOUSE_BUTTON.LEFT ) ) MoveNavigation(); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <strong>TargetNavigation<\/strong> \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0438 <strong>PlayerNavigation<\/strong> \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443. \u0422\u0430\u043a \u0436\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043a\u0443\u0431\u0430\u043c, \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0438 \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443 \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u0442\u044c Intersection \u0432 \u043e\u043a\u043d\u0435 Parameters, \u0447\u0442\u043e\u0431\u044b \u043b\u0443\u0447\u0443 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u043b\u043e \u0438 \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u043b\u0435\u0439\u043d\u0435. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c.  <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/9ca\/cc0\/ba5\/9cacc0ba5f2d57582edd182792d9422e.jpg\" alt=\"\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Intersection\" title=\"\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Intersection\" width=\"410\" height=\"484\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9ca\/cc0\/ba5\/9cacc0ba5f2d57582edd182792d9422e.jpg\" data-blurred=\"true\"\/><figcaption>\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 Intersection<\/figcaption><\/figure>\n<p>\u0424\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c6e\/2c4\/5f0\/c6e2c45f0b9d567b358a422bd3a3d410.png\" alt=\"\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unigine\" title=\"\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unigine\" width=\"1383\" height=\"806\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c6e\/2c4\/5f0\/c6e2c45f0b9d567b358a422bd3a3d410.png\"\/><figcaption>\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unigine<\/figcaption><\/figure>\n<pre><code class=\"cs\">public class NavigationAgent : Component { [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Speed = 4; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u043e\u0434\u044b \u043f\u043e \u043f\u0443\u0442\u0438 [ParameterSlider( Max = 60, Min = 0, Group = \"Agent\" )] public float RotationSpeed = 25; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u043d\u043e\u0434\u044b [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Radius = 0.4f; \/\/\u0420\u0430\u0434\u0438\u0443\u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Height = 0.5f; \/\/\u0412\u044b\u0441\u043e\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float StopDistance = 0.3f; \/\/\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterMask( Group = \"Parameter Mask\" )] public int NavigationMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u043c\u0435\u0448\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0431\u0443\u0434\u0435\u0442  [ParameterMask( Group = \"Parameter Mask\" )] public int ObstacleMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u043f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430  private bool _isRecalculate; \/\/\u0421\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private vec3 _pointDirection; \/\/\u0422\u043e\u0447\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private PathRoute _route; \/\/\u041a\u043b\u0430\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c  private void Init() { _route = new PathRoute(); InitRoute(); }  private void Update() { InitRoute(); MoveDirection(); RenderVisualizer(); }  private void InitRoute() { _route.NavigationMask = NavigationMask; _route.ObstacleMask = ObstacleMask; _route.Radius = Radius; _route.Height = Height; }  private void RenderVisualizer() { \/\/\u0420\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u043b\u0438\u043d\u0434\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u044b\u0441\u043e\u0442\u044b \u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 Visualizer.RenderCylinder( Radius, Height, node.WorldTransform, vec4.RED );  \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0443\u0442\u044c if ( _route.IsReached ) _route.RenderVisualizer( vec4.RED ); }  private void MoveDirection() { if ( _route.IsReached ) { if ( _route.Distance &lt;= StopDistance ) return;  vec3 direction = _route.GetPoint( 1 ) - _route.GetPoint( 0 ); if ( direction.Length2 > MathLib.EPSILON ) { \/\/\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u043e\u0434\u044b \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f quat directionRotation = new quat( MathLib.SetTo( vec3.ZERO, direction.Normalized, vec3.UP, MathLib.AXIS.Y ) ); quat newRotation = MathLib.Slerp( node.GetWorldRotation(), directionRotation, Game.IFps * RotationSpeed ); node.SetWorldRotation( newRotation );  \/\/\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u043e\u0434\u044b node.Translate( vec3.FORWARD * Game.IFps * Speed ); }  \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 if ( _isRecalculate ) _route.Create2D( node.WorldPosition, _pointDirection ); } }  public void SetDirection( in vec3 point, in bool recalculate = true ) { _pointDirection = point; _isRecalculate = recalculate;  _route.Create2D( node.WorldPosition, point ); } }<\/code><\/pre>\n<pre><code class=\"cs\">public class TargetNavigation : Component { [ShowInEditor] Node _target = null;  private NavigationAgent _agent = null;  private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); }  private void PostUpdate() { _agent.SetDirection( _target.WorldPosition, false ); } }<\/code><\/pre>\n<pre><code class=\"cs\">public class PlayerNavigation : Component { private NavigationAgent _agent = null; private WorldIntersection _intersection = new WorldIntersection(); private Player _playerCamera = null;  private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); _playerCamera = Game.Player;  Input.MouseHandle = Input.MOUSE_HANDLE.USER; }  private void Update() { if ( Input.IsMouseButtonDown( Input.MOUSE_BUTTON.LEFT ) ) MoveNavigation(); }  private void MoveNavigation() { ivec2 mousePosition = Input.MousePosition; vec3 start = _playerCamera.WorldPosition; vec3 end = start + _playerCamera.GetDirectionFromMainWindow( mousePosition.x, mousePosition.y ) * 100f;  Object intersectionObject = World.GetIntersection( start, end, 1, _intersection ); if ( intersectionObject ) _agent.SetDirection( _intersection.Point ); } }<\/code><\/pre>\n<p><a href=\"https:\/\/unigine.com\/\" rel=\"noopener noreferrer nofollow\">\u041e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0430\u0439\u0442 Unigine<\/a><\/p>\n<p><a href=\"https:\/\/developer.unigine.com\/\" rel=\"noopener noreferrer nofollow\">\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f Unigine<\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/716722\/\"> https:\/\/habr.com\/ru\/articles\/716722\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041a\u0440\u0430\u0442\u043a\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f<\/h3>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0446\u0435\u043d\u0430 \u0432 <strong>Unity<\/strong>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u043a\u0443\u0431, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0439 \u0438\u0433\u0440\u043e\u043a\u043e\u043c \u043c\u044b\u0448\u043a\u043e\u0439, \u0438 \u0441\u0438\u043d\u044f\u044f \u043a\u0430\u043f\u0441\u0443\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u043a\u0443\u0431\u043e\u043c. \u041e\u043d\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u043f\u043e \u0431\u0435\u043b\u043e\u043c\u0443 \u043f\u043b\u0435\u0439\u043d\u0443 \u0432\u043e\u043a\u0440\u0443\u0433 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439.  <\/p>\n<figure class=\"full-width\"><figcaption>\u0421\u043a\u0440\u0438\u043d\u0448\u043e\u0442 \u0438\u0437 Unity<\/figcaption><\/figure>\n<p>\u0411\u044b\u043b\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0435\u0442\u043a\u0430. \u041d\u0430 \u0437\u0435\u043b\u0435\u043d\u043e\u043c \u043a\u0443\u0431\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b <strong>NavMeshAgent<\/strong> \u0438 <strong>PlayerNavigation<\/strong>. \u0421\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 <strong>NavMeshAgent<\/strong> \u0438 <strong>TargetNavigation<\/strong>. \u041d\u0430 \u043a\u0440\u0430\u0441\u043d\u044b\u0445 \u043a\u0443\u0431\u0430\u043a \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <strong>NavMeshObstacle<\/strong>.  <\/p>\n<pre><code class=\"cs\">public class PlayerNavigation : MonoBehaviour { private NavMeshAgent _agent = null; private Camera _camera = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); _camera = Camera.main; }  private void Update() { if ( Input.GetMouseButtonDown( 0 ) ) { Ray ray = _camera.ScreenPointToRay( Input.mousePosition ); if ( Physics.Raycast( ray, out RaycastHit hit ) ) _agent.SetDestination( hit.point ); } } }<\/code><\/pre>\n<pre><code class=\"cs\">public class TargetNavigation : MonoBehaviour { [SerializeField] Transform _target = null; private NavMeshAgent _agent = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); }  private void Update() { _agent.SetDestination( _target.position ); } }<\/code><\/pre>\n<pre><code class=\"cs\">public class VisualPath : MonoBehaviour { private LineRenderer _lineRenderer = null; private NavMeshAgent _agent = null;  private void Start() { _agent = GetComponent&lt;NavMeshAgent>(); _lineRenderer = GetComponent&lt;LineRenderer>(); }  private void LateUpdate() { if ( _agent.hasPath ) { _lineRenderer.positionCount = _agent.path.corners.Length; _lineRenderer.SetPositions( _agent.path.corners ); } } }<\/code><\/pre>\n<h3>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0432 Unigine<\/h3>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0435\u043e\u0440\u0438\u0438.<\/p>\n<p>\u041e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0432 Unigine \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u043c\u0435\u0448\u0435\u043c (<strong>Navigation Mesh<\/strong>) \u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u043c \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u043c (<strong>Navigation Sector<\/strong>), \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0432 2D \u0438 3D \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 (\u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 2D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Z <strong>\u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f<\/strong>).<\/p>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448 &#8212; \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u0430 \u043c\u0435\u0448\u0430. <strong>\u0412\u0430\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c<\/strong>, \u0447\u0442\u043e \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 <strong>\u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430<\/strong>. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448 \u0438\u043b\u0438 \u0441\u0435\u043a\u0442\u043e\u0440 \u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u043f\u0443\u0442\u0438 <strong>\u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/strong>, \u0442\u0430\u043a \u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 <strong>\u0442\u043e\u043b\u044c\u043a\u043e 2D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430<\/strong>. \u0421\u0430\u043c \u043c\u0435\u0448 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 3D \u043c\u043e\u0434\u0435\u043b\u0438.<\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u043c\u0435\u0448<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/navigation\/navigation_mesh\/?rlang=cpp&amp;autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Navigation Mesh<\/a><\/p>\n<p>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440 &#8212; \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430. \u041e\u043d \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435 2D \u0438 3D \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432. \u0427\u0442\u043e\u0431\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0431\u044b\u043b \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043c\u0435\u0436\u0434\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c\u0438 \u0441\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0430\u0434\u0438\u0443\u0441 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0447\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043c\u043e\u0433\u043b\u0430 \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432. \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/navigation\/navigation_sector\/?rlang=cpp&amp;autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Navigation Sector<\/a><\/p>\n<p>Obstacle (\u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f) \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0433\u0438\u0431\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432 \u0444\u043e\u0440\u043c\u0435 \u043a\u0443\u0431\u0430, \u0441\u0444\u0435\u0440\u044b \u0438\u043b\u0438 \u043a\u0430\u043f\u0441\u0443\u043b\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438.<\/p>\n<figure class=\"\"><figcaption>\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u0443\u0431\u0430<\/figcaption><\/figure>\n<p><a href=\"https:\/\/developer.unigine.com\/ru\/docs\/future\/objects\/navigations\/obstacle\/?autotranslate=ru\" rel=\"noopener noreferrer nofollow\">\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e Obstacle<\/a><\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043c\u0438\u0440\u0430 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438  <\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0438\u0440 \u0438 \u043e\u0431\u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441\u043e \u0441\u0446\u0435\u043d\u043e\u0439 <strong>Unity<\/strong>.<\/p>\n<figure class=\"full-width\"><figcaption>\u041e\u0431\u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043c\u0438\u0440 \u0432 Unigine<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0439 \u0441\u0435\u043a\u0442\u043e\u0440 <strong>Create -> Navigation -> Navigation Sector<\/strong>. \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c \u0435\u0433\u043e \u0432\u044b\u0448\u0435 \u043f\u043b\u0435\u0439\u043d\u0430 \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u044f <strong>Size<\/strong> \u0432 \u043e\u043a\u043d\u0435 <strong>Parameters<\/strong>, \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0432 \u0444\u043e\u0440\u043c\u0435 \u0443\u0440\u043e\u0432\u043d\u044f.  <\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u0435\u043a\u0442\u043e\u0440<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043a\u0440\u0430\u0441\u043d\u044b\u0435 \u043a\u0443\u0431\u044b, \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0438\u0445 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f <strong>Create -> Navigation -> Obstacle Box<\/strong>.  <\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f<\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u0437\u043e\u043d\u044b \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439, \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c <strong>\u0445\u0435\u043b\u043f\u0435\u0440\u044b<\/strong>.<\/p>\n<figure class=\"\"><figcaption>\u0412\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432 \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u0439<\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption>\u0413\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0438\u0440<\/figcaption><\/figure>\n<h3>\u041a\u043b\u0430\u0441\u0441 PathRoute  <\/h3>\n<p><strong>PathRoute<\/strong> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u0447\u043a\u0438 \u043f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043c\u0435\u0436\u0434\u0443 A \u0438 B \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0432\u0443\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432: <strong>Create2D(vec3 A, vec3 B)<\/strong> \u0438 <strong>Create3D(vec3 A, vec3 B)<\/strong>.<\/p>\n<p>\u0417\u0430\u0434\u0430\u0432 \u043c\u0430\u0441\u043a\u0438 \u0434\u043b\u044f \u0441\u0435\u043a\u0442\u043e\u0440\u0430 (\u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430) \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f, \u043c\u043e\u0436\u043d\u043e \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<figure class=\"\"><figcaption>\u041c\u0430\u0441\u043a\u0430 \u0434\u043b\u044f \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430<\/figcaption><\/figure>\n<p>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0440\u0430\u0434\u0438\u0443\u0441 \u0438 \u0432\u044b\u0441\u043e\u0442\u0443. \u0415\u0441\u043b\u0438 \u0441\u0435\u043a\u0442\u043e\u0440 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435, \u0442\u043e \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 <strong>\u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0438\u0437 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438<\/strong>.<\/p>\n<figure class=\"full-width\"><figcaption>\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432<\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0441\u0435\u043a\u0442\u043e\u0440\u043e\u0432<\/figcaption><\/figure>\n<h3>\u041d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442  <\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430. \u0417\u0430\u0434\u0430\u0434\u0438\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u0430\u0433\u0435\u043d\u0442\u0430: \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u043f\u043e\u0432\u043e\u0440\u043e\u0442, \u0440\u0430\u0434\u0438\u0443\u0441, \u0432\u044b\u0441\u043e\u0442\u0443, \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0438 \u043c\u0430\u0441\u043a\u0438. \u0412\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c <strong>\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043c\u0435\u0448\u0430<\/strong> \u0438\u043b\u0438 <strong>\u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u043a\u0442\u043e\u0440\u0430<\/strong>!<\/p>\n<pre><code class=\"cs\">public class NavigationAgent : Component { [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Speed = 4; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043d\u043e\u0434\u044b \u043f\u043e \u043f\u0443\u0442\u0438 [ParameterSlider( Max = 60, Min = 0, Group = \"Agent\" )] public float RotationSpeed = 25; \/\/\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u043d\u043e\u0434\u044b [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Radius = 0.4f; \/\/\u0420\u0430\u0434\u0438\u0443\u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float Height = 0.5f; \/\/\u0412\u044b\u0441\u043e\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterSlider( Max = 10, Min = 0, Group = \"Agent\" )] public float StopDistance = 0.3f; \/\/\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043e \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 [ParameterMask( Group = \"Parameter Mask\" )] public int NavigationMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u0441\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u043b\u0438 \u043c\u0435\u0448\u0430 [ParameterMask( Group = \"Parameter Mask\" )] public int ObstacleMask = 1; \/\/\u041c\u0430\u0441\u043a\u0430 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0438\u044f \u043e\u0431\u0445\u043e\u0434\u0430 \u043f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 }<\/code><\/pre>\n<p>\u0417\u0430\u0434\u0430\u0434\u0438\u043c \u0442\u0440\u0438 \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u044b\u0445 \u043f\u043e\u043b\u044f \u0434\u043b\u044f \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u0430.\u00a0<\/p>\n<pre><code class=\"cs\">private bool _isRecalculate; \/\/\u0421\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private vec3 _pointDirection; \/\/\u0422\u043e\u0447\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 private PathRoute _route; \/\/\u041a\u043b\u0430\u0441\u0441 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <strong>InitRoute<\/strong> \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044f\u043c \u043a\u043b\u0430\u0441\u0441\u0430 <strong>PathRoute<\/strong> \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0438\u0437\u0432\u043d\u0435. <\/p>\n<pre><code class=\"cs\">private void InitRoute() {     _route.NavigationMask = NavigationMask;     _route.ObstacleMask = ObstacleMask;     _route.Radius = Radius;     _route.Height = Height; }<\/code><\/pre>\n<p>\u0418 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Init<\/strong> \u0438 <strong>Update<\/strong>.  <\/p>\n<pre><code class=\"cs\">private void Init() {     _route = new PathRoute();     InitRoute(); }  private void Update() {     InitRoute(); } <\/code><\/pre>\n<p>\u0414\u0430\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442, \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <strong>RenderVisualizer<\/strong> \u0438 \u0432\u044b\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong>. \u0421\u0430\u043c\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0432 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 Init \u201c<strong>Visualizer.Enabled = true;<\/strong>\u201d \u0438\u043b\u0438 \u0432\u0432\u0435\u0434\u044f \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443 \u201c<strong>show_visualizer 1<\/strong>\u201d.<\/p>\n<pre><code class=\"cs\">private void RenderVisualizer() { \/\/\u0420\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u043b\u0438\u043d\u0434\u0440 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u044b\u0441\u043e\u0442\u044b \u0438 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 Visualizer.RenderCylinder( Radius, Height, node.WorldTransform, vec4.RED );      \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0435\u0433\u043e \u043f\u0443\u0442\u044c if ( _route.IsReached )     _route.RenderVisualizer( vec4.RED ); }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 <strong>SetDirection<\/strong>. \u041f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u0443\u044e \u0442\u043e\u0447\u043a\u0443 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<pre><code class=\"cs\">public void SetDirection( in vec3 point, in bool recalculate = true ) { _pointDirection = point; _isRecalculate = recalculate;  _route.Create2D( node.WorldPosition, point ); }<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0430\u0433\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430. \u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <strong>MoveDirection<\/strong>. \u0412\u043d\u0430\u0447\u0430\u043b\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e.<\/p>\n<pre><code class=\"cs\">private void MoveDirection() { if ( _route.IsReached ) { if ( _route.Distance &lt;= StopDistance ) return;         \/\/\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435     } }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0432\u0435\u043a\u0442\u043e\u0440 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u0442\u043e\u0447\u043a\u0430\u043c\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u0447\u0442\u043e \u043e\u043d \u0435\u0449\u0435 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d.<\/p>\n<pre><code class=\"cs\">vec3 direction = _route.GetPoint( 1 ) - _route.GetPoint( 0 ); if ( direction.Length2 > MathLib.EPSILON ) {     \/\/\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435   }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u041c\u0435\u0442\u043e\u0434\u043e\u043c <strong>MathLib.SetTo<\/strong> \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0438 \u0438\u0437 \u043d\u0435\u0435 <strong>quat<\/strong> \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f. \u0417\u0430\u0442\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u043e\u043c <strong>MathLib.Slerp<\/strong> \u0431\u0443\u0434\u0435\u043c \u043f\u043b\u0430\u0432\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u043e\u0434\u044b \u0430\u0433\u0435\u043d\u0442\u0430.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u043e\u0434\u044b \u0432 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f quat directionRotation = new quat( MathLib.SetTo( vec3.ZERO, direction.Normalized, vec3.UP, MathLib.AXIS.Y ) ); quat newRotation = MathLib.Slerp( node.GetWorldRotation(), directionRotation, Game.IFps * RotationSpeed ); node.SetWorldRotation( newRotation );<\/code><\/pre>\n<p>\u0417\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u043d\u043e\u0434\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u0432\u043f\u0435\u0440\u0435\u0434 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u0435\u0431\u044f.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043d\u043e\u0434\u044b node.Translate( vec3.FORWARD * Game.IFps * Speed );<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c, \u043d\u0443\u0436\u0435\u043d \u043b\u0438 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438.  <\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 if ( _isRecalculate )     _route.Create2D( node.WorldPosition, _pointDirection );<\/code><\/pre>\n<p>\u0412\u044b\u0437\u043e\u0432\u0435\u043c \u044d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong> \u043c\u0435\u0436\u0434\u0443 <strong>InitRoute<\/strong> \u0438 <strong>RenderVisualizer<\/strong>.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442 \u043a \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443 \u0438 \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435.<\/p>\n<figure class=\"\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 Navigation Agent<\/figcaption><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <strong>TargetNavigation<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u0437\u0435\u043b\u0435\u043d\u044b\u043c \u043a\u0443\u0431\u043e\u043c. \u0410\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043f\u0435\u0440\u0435\u0440\u0430\u0441\u0447\u0435\u0442 \u0432 <strong>NavigationAgent<\/strong> \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0448\u0430 \u0442\u043e\u0447\u043a\u0430 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>SetDirection<\/strong> \u0432 <strong>PostUpdate<\/strong>.<\/p>\n<pre><code class=\"cs\">public class TargetNavigation : Component { [ShowInEditor] Node _target = null;  private NavigationAgent _agent = null;  private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); }  private void PostUpdate() { _agent.SetDirection( _target.WorldPosition, false ); } }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 <strong>PlayerNavigation<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u0438.<\/p>\n<p>\u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0442\u0440\u0438 \u043f\u043e\u043b\u044f: \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0430\u0433\u0435\u043d\u0442, \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0438 \u043a\u0430\u043c\u0435\u0440\u0430.<\/p>\n<pre><code class=\"cs\">public class PlayerNavigation : Component { private NavigationAgent _agent = null; private WorldIntersection _intersection = new WorldIntersection(); private Player _playerCamera = null; }<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Init<\/strong> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0430\u0433\u0435\u043d\u0442\u0430 \u0438 \u043a\u0430\u043c\u0435\u0440\u0443. \u0422\u0430\u043a\u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u043a\u0443\u0440\u0441\u043e\u0440 \u043c\u044b\u0448\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0432\u0438\u0434\u0438\u043c\u044b\u043c.  <\/p>\n<pre><code class=\"cs\">private void Init() { _agent = GetComponent&lt;NavigationAgent>( node ); _playerCamera = Game.Player;  Input.MouseHandle = Input.MOUSE_HANDLE.USER; }<\/code><\/pre>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043b\u0443\u0447, \u0432 \u0442\u043e\u0447\u043a\u0435 \u0441\u043e\u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443.  <\/p>\n<pre><code class=\"cs\">private void MoveNavigation() { ivec2 mousePosition = Input.MousePosition; vec3 start = _playerCamera.WorldPosition; vec3 end = start + _playerCamera.GetDirectionFromMainWindow( mousePosition.x, mousePosition.y ) * 100f;  Object intersectionObject = World.GetIntersection( start, end, 1, _intersection ); if ( intersectionObject ) _agent.SetDirection( _intersection.Point ); }<\/code><\/pre>\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>Update<\/strong> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 <strong>MoveNavigation<\/strong> \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u041b\u041a\u041c.  <\/p>\n<pre><code class=\"cs\">private void Update() { if ( Input.IsMouseButtonDown( Input.MOUSE_BUTTON.LEFT ) ) MoveNavigation(); }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 <strong>TargetNavigation<\/strong> \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0438 <strong>PlayerNavigation<\/strong> \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 \u043a\u0443\u0431\u0443. \u0422\u0430\u043a \u0436\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u043a\u0440\u0430\u0441\u043d\u044b\u043c \u043a\u0443\u0431\u0430\u043c, \u0441\u0438\u043d\u0435\u0439 \u043a\u0430\u043f\u0441\u0443\u043b\u0435 \u0438 \u0437\u0435\u043b\u0435\u043d\u043e\u043c\u0443 <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-394564","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394564","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=394564"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394564\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=394564"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=394564"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=394564"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}