{"id":481323,"date":"2026-05-28T03:47:59","date_gmt":"2026-05-28T03:47:59","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=481323"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=481323","title":{"rendered":"\u041f\u0438\u0448\u0435\u043c Third Person Controller \u043d\u0430 MonoGame. \u0427\u0430\u0441\u0442\u044c I"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Third Person Controller \u043d\u0430 \u0431\u0430\u0437\u0435 MonoGame.<\/p>\n<p>\u0421\u0435\u0440\u0438\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439, \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0445 \u0441 \u043e\u0441\u043d\u043e\u0432\u0430\u043c\u0438 MonoGame \u0438 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0438.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0435\u043c\u0430\u0445:<\/p>\n<ul>\n<li>\n<p>C#<\/p>\n<\/li>\n<li>\n<p>MonoGame<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u044b 3D-\u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u2014 \u043c\u0430\u0442\u0440\u0438\u0446\u044b, \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u0430\u043c\u0435\u0440\u044b \u0432 3D-\u0441\u0446\u0435\u043d\u0435 \u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 <code>world<\/code>, <code>view<\/code> \u0438 <code>projection<\/code> \u043c\u0430\u0442\u0440\u0438\u0446\u044b<\/p>\n<\/li>\n<li>\n<p>\u0411\u0430\u0437\u043e\u0432\u044b\u0439 3D-\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 MonoGame (<code>BasicEffect<\/code>, <code>SkinnedEffect<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0421\u043a\u0435\u043b\u0435\u0442\u043d\u0430\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f (\u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0441 \u0447\u0435\u043c-\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u2014 \u0432 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0437\u043d\u0430\u043c\u0435\u043d\u0438\u0442\u044b\u0435 Reimers Tutorials:<\/p>\n<p><a href=\"https:\/\/github.com\/simondarksidej\/XNAGameStudio\/wiki\/RiemersArchiveOverview\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/simondarksidej\/XNAGameStudio\/wiki\/RiemersArchiveOverview<\/a><\/p>\n<h3>DigitalRiseModel<\/h3>\n<p>\u041d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0439 \u0441\u0435\u0440\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:<\/p>\n<p><a href=\"https:\/\/github.com\/rds1983\/DigitalRiseModel\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/rds1983\/DigitalRiseModel<\/a><\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 API \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 3D-\u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0432 MonoGame.<\/p>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c 3D-\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b (\u043a\u0443\u0431\u044b, \u0441\u0444\u0435\u0440\u044b, \u043a\u0430\u043f\u0441\u0443\u043b\u044b \u0438 \u0442.\u0434.) \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435<\/p>\n<\/li>\n<li>\n<p>\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u0445 <code>gltf\/glb<\/code><\/p>\n<\/li>\n<li>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u043a\u0435\u043b\u0435\u0442\u043d\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439<\/p>\n<\/li>\n<\/ul>\n<h3>No Content Pipeline<\/h3>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Content Pipeline.<\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Content Pipeline, \u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043b \u0437\u0434\u0435\u0441\u044c:<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/1039344\/\" rel=\"noopener noreferrer nofollow\">https:\/\/habr.com\/ru\/articles\/1039344\/<\/a><\/p>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u043c\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:<\/p>\n<p><a href=\"https:\/\/github.com\/rds1983\/XNAssets\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/rds1983\/XNAssets<\/a><\/p>\n<p>\u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u00ab\u0441\u044b\u0440\u043e\u043c\u00bb \u0432\u0438\u0434\u0435 \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<h3>\u0427\u0430\u0441\u0442\u044c I<\/h3>\n<p>\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0433\u0435\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0432\u0438\u0434\u0435 \u043a\u0430\u043f\u0441\u0443\u043b\u044b. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433, \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u044b\u0436\u043a\u0438.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6a17bbdc105c2159dcbf30fa\" data-style=\"\" id=\"6a17bbdc105c2159dcbf30fa\" width=\"\" data-habr-games=\"\"><\/div>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u043c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u0430\u043f\u0441\u0443\u043b\u0443 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b<\/h2>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 MonoGame-\u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 \u043b\u044e\u0431\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>DesktopGL<\/code>).<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 NuGet-\u043f\u0430\u043a\u0435\u0442:<\/p>\n<p><a href=\"https:\/\/www.nuget.org\/packages\/DigitalRiseModel.MonoGame\/\" rel=\"noopener noreferrer nofollow\">https:\/\/www.nuget.org\/packages\/DigitalRiseModel.MonoGame\/<\/a><\/p>\n<p>\u041e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0435\u0442 \u0438 <code>XNAssets<\/code>.<\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0430\u0440\u0445\u0438\u0432:<\/p>\n<p><a href=\"https:\/\/github.com\/rds1983\/ThirdPersonTutorial\/raw\/refs\/heads\/master\/Step1-Capsule\/Assets.zip\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/rds1983\/ThirdPersonTutorial\/raw\/refs\/heads\/master\/Step1-Capsule\/Assets.zip<\/a><\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u0443\u0439\u0442\u0435 \u0435\u0433\u043e (\u043e\u043d \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u0441\u0435\u0433\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 <code>checker.dds<\/code>) \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 <code>.csproj<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"xml\">&lt;ItemGroup&gt;  &lt;None Update=\"Assets\\**\\*.*\"&gt;    &lt;CopyToOutputDirectory&gt;PreserveNewest&lt;\/CopyToOutputDirectory&gt;  &lt;\/None&gt;&lt;\/ItemGroup&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0430\u0441\u0441\u0435\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 Output Directory.<\/p>\n<h3>\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430<\/h3>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0448\u0435\u0433\u043e <code>Game<\/code>-\u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u0437\u0430\u0434\u0430\u044e\u0449\u0443\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0432\u044b\u0441\u043e\u0442\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430:<\/p>\n<pre><code class=\"cs\">\/\/ Hero ground heightprivate const float DefaultY = 1;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f:<\/p>\n<pre><code class=\"cs\">\/\/ Stock effect with directional lighting and texturingprivate BasicEffect _basicEffect;\/\/ Ground plane textureprivate Texture2D _textureGround;\/\/ Ground plane meshprivate DrMesh _meshGround;\/\/ Capsule mesh for the playerprivate DrMesh _meshHero;\/\/ Hero position in world spaceprivate Vector3 _heroPosition;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>DrMesh<\/code> \u2014 \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 <code>DigitalRiseModel<\/code>. \u041f\u043e \u0441\u0443\u0442\u0438 \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e <code>Mesh<\/code> \u0438\u0437 MonoGame.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c <code>LoadContent<\/code>:<\/p>\n<pre><code class=\"cs\">protected override void LoadContent(){base.LoadContent();\/\/ Load ground texturevar assetManager = AssetManager.CreateFileAssetManager(Path.Combine(AppContext.BaseDirectory, \"Assets\"));_textureGround = assetManager.LoadTexture2D(GraphicsDevice, \"Textures\/checker.dds\");\/\/ Create ground and hero meshes_meshGround = MeshPrimitives.CreatePlaneMesh(GraphicsDevice, uScale: 50, vScale: 50, normalDirection: NormalDirection.UpY);_meshHero = MeshPrimitives.CreateCapsuleMesh(GraphicsDevice);\/\/ Set up rendering effect with lighting_basicEffect = new BasicEffect(GraphicsDevice) { LightingEnabled = true };_basicEffect.DirectionalLight0.Enabled = true;_basicEffect.DirectionalLight0.Direction = new Vector3(-1, -1, -1);_basicEffect.DirectionalLight0.DiffuseColor = Color.White.ToVector3();\/\/ Start hero at world center_heroPosition = new Vector3(0, DefaultY, 0);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u044f\u043c\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u043e:<\/p>\n<ul>\n<li>\n<p>\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0437\u0435\u043c\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0448 \u0437\u0435\u043c\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u0430\u043f\u0441\u0443\u043b\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430<\/p>\n<\/li>\n<li>\n<p>\u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u0437\u0430\u0434\u0430\u0451\u043c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0433\u0435\u0440\u043e\u044f<\/p>\n<\/li>\n<\/ul>\n<h3>\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432: DrawMesh \u0438 ToMatrix<\/p>\n<h4>DrawMesh<\/h4>\n<pre><code class=\"cs\">\/\/\/ &lt;summary&gt;Render a mesh with color and texture.&lt;\/summary&gt;private void DrawMesh(DrMesh mesh, Matrix world, Color color, Texture2D texture){_basicEffect.DiffuseColor = color.ToVector3();_basicEffect.TextureEnabled = texture != null;_basicEffect.Texture = texture;_basicEffect.World = world;var device = GraphicsDevice;foreach (var part in mesh.MeshParts){device.SetVertexBuffer(part.VertexBuffer);device.Indices = part.IndexBuffer;foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes){pass.Apply();device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, part.PrimitiveCount);}}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 \u0440\u0438\u0441\u0443\u0435\u0442 \u043c\u0435\u0448 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043c\u0430\u0442\u0440\u0438\u0446\u043e\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0446\u0432\u0435\u0442\u043e\u043c \u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439.<\/p>\n<h4>ToMatrix<\/h4>\n<pre><code class=\"cs\">\/\/\/ &lt;summary&gt;Build transform matrix from position, scale, and rotation (TRS order).&lt;\/summary&gt;private static Matrix ToMatrix(Vector3 position, Vector3 scale, float yaw, float pitch, float roll){var scaleTransform = Matrix.CreateScale(scale);var rotation = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(yaw), MathHelper.ToRadians(pitch), MathHelper.ToRadians(roll));var translation = Matrix.CreateTranslation(position);return scaleTransform * rotation * translation;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/p>\n<pre><code>Scale -&gt; Rotate -&gt; Translate<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 MonoGame\/XNA \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0437\u0430\u0442\u0435\u043c \u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0438\u0440.<\/p>\n<hr\/>\n<h2>Hero, Camera Mount \u0438 Camera<\/h2>\n<p>\u0421\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b \u0432 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435.<\/p>\n<p>\u041c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e third-person \u043a\u0430\u043c\u0435\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f:<\/p>\n<ul>\n<li>\n<p>\u0412\u0441\u0435\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043c\u044b\u0448\u043a\u043e\u0439 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443 \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437 (\u043a\u0430\u043a \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0433\u0440)<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0442\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ddd\/977\/085\/ddd9770850f13c55ed4cf88731097bde.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/ddd\/977\/085\/ddd9770850f13c55ed4cf88731097bde.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/ddd\/977\/085\/ddd9770850f13c55ed4cf88731097bde.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 3 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><code>Hero<\/code> (\u043a\u0430\u043f\u0441\u0443\u043b\u0430) &#8212; \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436<\/p>\n<\/li>\n<li>\n<p><code>Camera Mount<\/code> \u2014 \u0436\u0451\u0441\u0442\u043a\u0438\u0439 \u201c\u0448\u0442\u0430\u0442\u0438\u0432\u201d, \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0451\u043d\u043d\u044b\u0439 \u043a \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430. \u0423 \u0435\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0448\u0430\u0440\u043d\u0438\u0440, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437<\/p>\n<\/li>\n<li>\n<p><code>Camera<\/code> &#8212; \u0441\u0430\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u0448\u0442\u0430\u0442\u0438\u0432\u0430. \u041e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0430 \u043d\u0430 180 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432 \u043f\u043e \u043e\u0441\u0438 Y, \u0434\u0430\u0431\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u043f\u0438\u043d\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043b\u0435\u0432\u043e-\u0432\u043f\u0440\u0430\u0432\u043e \u2014 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u0448\u0442\u0430\u0442\u0438\u0432 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0448\u0442\u0430\u0442\u0438\u0432 \u2014 \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u043a\u043b\u043e\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0438\u043c, \u043d\u043e \u0441\u0430\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043a\u0440\u0435\u043d\u0438\u0442\u0441\u044f.<\/p>\n<p>\u0412\u0441\u044f \u044d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0442\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 <code>Hero<\/code> \u0432 \u043c\u0438\u0440\u0435 (<code>Vector3 _heroPosition<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u0433\u0435\u0440\u043e\u044f \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u0441\u0438 Y (<code>float _heroYaw<\/code>)<\/p>\n<\/li>\n<li>\n<p>\u0423\u0433\u043e\u043b \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 <code>Camera Mount<\/code> \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u0441\u0438 X (<code>float _cameraMountPitch<\/code>)<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u0435\u0440\u0432\u0443\u044e \u043c\u044b \u0443\u0436\u0435 \u0437\u0430\u0434\u0430\u043b\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435:<\/p>\n<pre><code class=\"cs\">\/\/ Hero body yaw rotation in degreesprivate float _heroYaw;\/\/ Camera mount pitch rotation in degreesprivate float _cameraMountPitch;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0441\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a\u0430\u043c\u0435\u0440\u044b(\u0430 \u043c\u044b \u044d\u0442\u043e\u0433\u043e \u0445\u043e\u0442\u0438\u043c, \u0434\u0430\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 camera view), \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0438.<\/p>\n<h3>\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0441\u0446\u0435\u043d\u044b<\/h3>\n<p>\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u043a\u0430\u043c\u0435\u0440\u044b:<\/p>\n<pre><code class=\"cs\">\/\/ Camera near clipping planeprivate const float NearPlaneDistance = 0.1f;\/\/ Camera far clipping planeprivate const float FarPlaneDistance = 1000.0f;\/\/ Camera field of view in degreesprivate const float ViewAngle = 60.0f;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <code>Draw<\/code>, \u0433\u0434\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cs\">protected override void Draw(GameTime gameTime){base.Draw(gameTime);var device = GraphicsDevice;device.Clear(Color.Black);\/\/ Set GPU statesdevice.DepthStencilState = DepthStencilState.Default;device.RasterizerState = RasterizerState.CullCounterClockwise;device.BlendState = BlendState.AlphaBlend;device.SamplerStates[0] = SamplerState.LinearWrap;\/\/ Set projectionvar projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(ViewAngle),device.Viewport.AspectRatio,NearPlaneDistance, FarPlaneDistance);_basicEffect.Projection = projection;\/\/ Build camera hierarchy: hero body -&gt; camera mount (head) -&gt; cameravar heroTransform = ToMatrix(_heroPosition, Vector3.One, _heroYaw, 0, 0);var cameraMountOffset = new Vector3(0, 1f, 0); \/\/ Camera mount is on the head level - 1 unit above hero positionvar cameraMountTransform = ToMatrix(cameraMountOffset, Vector3.One, 0, _cameraMountPitch, 0) * heroTransform;var cameraOffset = new Vector3(0, 0, -5); \/\/ Camera is 5 units behind the mountvar cameraTransform = ToMatrix(cameraOffset, Vector3.One, 180, 0, 0) * cameraMountTransform; \/\/ Rotate 180 degrees to look back at the hero_basicEffect.View = Matrix.Invert(cameraTransform);\/\/ Draw ground and heroDrawMesh(_meshGround, Matrix.CreateScale(200, 1, 200), Color.White, _textureGround);DrawMesh(_meshHero, heroTransform, Color.Green, null);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 heroTransform. \u0417\u0430\u0442\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f cameraMountTransform. \u041e\u043d \u0441\u043c\u0435\u0448\u0451\u043d \u043d\u0430 1 \u043f\u043e \u043e\u0441\u0438 Y(cameraMountOffset), \u0434\u0430\u0431\u044b \u0431\u044b\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0433\u043e\u043b\u043e\u0432\u044b. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f cameraTransform. \u041e\u043d \u0441\u043c\u0435\u0449\u0435\u043d\u0430 \u043d\u0430 -5 \u043f\u043e \u043e\u0441\u0438 Y \u0438 \u043f\u043e\u0432\u0451\u0440\u043d\u0443\u0442\u0430 \u043d\u0430 180 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u043f\u0438\u043d\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 View Matrix \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443:<\/p>\n<pre><code class=\"cs\">_basicEffect.View = Matrix.Invert(cameraTransform);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c:<\/p>\n<p><code>View Matrix<\/code> \u2014 \u044d\u0442\u043e \u043d\u0435 transform \u043a\u0430\u043c\u0435\u0440\u044b.<\/p>\n<p>\u041d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u044d\u0442\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043c\u0438\u0440 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b.<\/p>\n<p>\u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043a\u0430\u043c\u0435\u0440\u0430 \u0432 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u00ab\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043c\u0438\u0440\u00bb \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f <code>View Matrix<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0438\u0440\u043e\u0432\u0443\u044e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a\u0430\u043c\u0435\u0440\u044b.<\/p>\n<h3>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u0442\u043e\u0433<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438\u0433\u0440\u0443 \u0441\u0435\u0439\u0447\u0430\u0441, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/90a\/cbc\/acc\/90acbcaccff851a169a116f4337a5bc3.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/\/post_images\/90a\/cbc\/acc\/90acbcaccff851a169a116f4337a5bc3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/\/post_images\/90a\/cbc\/acc\/90acbcaccff851a169a116f4337a5bc3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043e\u0434\u043d\u0430\u043a\u043e \u043a\u0430\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0434\u0432\u0438\u0436\u043d\u043e\u0439.<\/p>\n<h3>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0443\u044e \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u044b\u0448\u043a\u0438:<\/p>\n<pre><code class=\"cs\">\/\/ Mouse look sensitivity multiplierprivate const float MouseSensitivity = 0.2f;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u044b\u0448\u043a\u0438:<\/p>\n<pre><code class=\"cs\">\/\/ Previous mouse state for delta calculationprivate MouseState? _oldMouse = null;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 Update \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cs\">protected override void Update(GameTime gameTime){base.Update(gameTime);\/\/ Handle mouse input for camera rotationvar mouse = Mouse.GetState();if (_oldMouse != null){\/\/ Rotate hero by mouse X deltavar horizontalRotation = -(int)((mouse.X - _oldMouse.Value.X) * MouseSensitivity);_heroYaw += horizontalRotation;\/\/ Tilt camera by mouse Y deltavar verticalRotation = -(int)((mouse.Y - _oldMouse.Value.Y) * MouseSensitivity);_cameraMountPitch += verticalRotation;\/\/ Clamp pitch to valid range (-20 to 70 degrees)_cameraMountPitch = MathHelper.Clamp(_cameraMountPitch, -20, 70);}_oldMouse = mouse;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043a\u043e\u0434 \u0432\u0435\u0441\u044c\u043c\u0430 \u043e\u0447\u0435\u0432\u0438\u0434\u0435\u043d. \u041c\u044b \u043c\u0435\u043d\u044f\u0435\u043c \u0440\u0430\u043d\u0435\u0435 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u0435 _heroYaw \u0438 _cameraMountPitch \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044b\u0448\u043a\u0438(\u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u044f _heroYaw \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u0434\u043b\u044f _cameraMountPitch).<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438\u0433\u0440\u0443 \u0438 \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6a17bbdc7475126c51f65a22\" data-style=\"\" id=\"6a17bbdc7475126c51f65a22\" width=\"\" data-habr-games=\"\"><\/div>\n<h3>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430<\/h3>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">\/\/ Movement speed per frameprivate const float MovementSpeed = 0.1f;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432 Update \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043b\u0430\u0432\u0438\u0448 WASD:<\/p>\n<pre><code class=\"cs\">\/\/ WASD movementvar velocity = Vector3.Zero;var heroTransform = ToMatrix(_heroPosition, Vector3.One, _heroYaw, 0, 0);var keyboard = Keyboard.GetState();if (keyboard.IsKeyDown(Keys.W))velocity = heroTransform.Forward * -MovementSpeed;else if (keyboard.IsKeyDown(Keys.S))velocity = heroTransform.Forward * MovementSpeed;else if (keyboard.IsKeyDown(Keys.A))velocity = heroTransform.Right * MovementSpeed;else if (keyboard.IsKeyDown(Keys.D))velocity = heroTransform.Right * -MovementSpeed;_heroPosition += velocity;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 Hero, \u0434\u0430\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0438\u0437 \u043d\u0435\u0451 \u0432\u0435\u043a\u0442\u043e\u0440\u0430 Forward(\u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432\u043f\u0435\u0440\u0451\u0434-\u043d\u0430\u043f\u0430\u0434) \u0438 Right(\u0434\u043b\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432\u043b\u0435\u0432\u043e-\u0432\u043f\u0440\u0430\u0432\u043e). \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u044d\u0442\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430.<\/p>\n<p>\u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438\u0433\u0440\u0443 \u0438 \u0443\u0431\u0435\u0434\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/6a17bbdc3bae625a30f2d2ef\" data-style=\"\" id=\"6a17bbdc3bae625a30f2d2ef\" width=\"\" data-habr-games=\"\"><\/div>\n<h3>\u041f\u0440\u044b\u0436\u043a\u0438<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c &#8212; \u044d\u0442\u043e \u043f\u0440\u044b\u0436\u043a\u0438.<\/p>\n<p>\u0421\u0440\u0430\u0437\u0443 \u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043f\u0440\u044b\u0436\u043a\u0430\u0445 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u043b\u0430\u0441\u044c \u0438\u043d\u0435\u0440\u0446\u0438\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u0447\u043d\u0451\u043c \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e \u0441 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442:<\/p>\n<pre><code class=\"cs\">\/\/ Jump gravity acceleration per secondprivate const float Gravity = 12f;\/\/ Jump initial velocityprivate const float JumpForce = 10f;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0442\u0430\u043a \u0436\u0435 \u043f\u0430\u0440\u044b \u043f\u043e\u043b\u0435\u0439, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u044b\u0436\u043a\u0430<\/p>\n<pre><code class=\"cs\">\/\/ Jump state and physicsprivate DateTime? _jumpStarted;private Vector3 _jumpMovement;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u0432\u044b\u0448\u0435\u043f\u0440\u0438\u0432\u0435\u0434\u0451\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">\/\/ Handle movement and jumpingif (_jumpStarted == null){\/\/ WASD movementvar velocity = Vector3.Zero;var heroTransform = ToMatrix(_heroPosition, Vector3.One, _heroYaw, 0, 0);var keyboard = Keyboard.GetState();if (keyboard.IsKeyDown(Keys.W))velocity = heroTransform.Forward * -MovementSpeed;else if (keyboard.IsKeyDown(Keys.S))velocity = heroTransform.Forward * MovementSpeed;else if (keyboard.IsKeyDown(Keys.A))velocity = heroTransform.Right * MovementSpeed;else if (keyboard.IsKeyDown(Keys.D))velocity = heroTransform.Right * -MovementSpeed;_heroPosition += velocity;if (keyboard.IsKeyDown(Keys.Space)){\/\/ Jump_jumpStarted = DateTime.Now;_jumpMovement = velocity;}}else{\/\/ When moving with acceleration\/\/ Formula for the jump height: h = h0 + v0 * t - 0.5 * g * t^2\/\/ Where h0 is the initial height(DefaultY), v0 is the initial jump velocity(JumpForce), g is the gravity(JumpGravity), and t is the time passed since jump startedvar t = (float)(DateTime.Now - _jumpStarted.Value).TotalSeconds;var jumpHeight = DefaultY + (JumpForce * t) - (0.5f * Gravity * t * t);_heroPosition.Y = jumpHeight;_heroPosition += _jumpMovement;\/\/ Land when reaching groundif (_heroPosition.Y &lt;= DefaultY){_heroPosition.Y = DefaultY;_jumpStarted = null;}}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0441\u0451 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e. \u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043f\u0440\u043e\u0431\u0435\u043b\u0430, \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u0440\u0435\u043c\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u044b\u0436\u043a\u0430 \u0438 \u0438\u043d\u0435\u0440\u0446\u0438\u044e.<\/p>\n<p>\u0412 \u0441\u0430\u043c\u043e\u043c \u0436\u0435 \u043f\u0440\u044b\u0436\u043a\u0435, \u043c\u044b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0441\u043e\u0442\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043f\u043e \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0441\u043e \u0448\u043a\u043e\u043b\u044c\u043d\u044b\u0445 \u0432\u0440\u0435\u043c\u0451\u043d \u0444\u043e\u0440\u043c\u0443\u043b\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435\u043c. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u0430\u0434\u0430\u0435\u043c \u043d\u0438\u0436\u0435 DefaultY, \u0442\u043e \u043e\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u0440\u044b\u0436\u043e\u043a.<\/p>\n<p>\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b \u043e\u043a\u043e\u043d\u0447\u0435\u043d. \u041d\u0430\u0448\u0430 \u0438\u0433\u0440\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e \u0438\u0437 \u043d\u0430\u0447\u0430\u043b\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0437\u0434\u0435\u0441\u044c:<\/p>\n<p><a href=\"https:\/\/github.com\/rds1983\/ThirdPersonTutorial\/blob\/master\/Step1-Capsule\/MyGame.cs\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/rds1983\/ThirdPersonTutorial\/blob\/master\/Step1-Capsule\/MyGame.cs<\/a><\/p>\n<\/div>\n<p>\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\/1040382\/\">https:\/\/habr.com\/ru\/articles\/1040382\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u043e\u0432 \u043c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 Third Person Controller \u043d\u0430 \u0431\u0430\u0437\u0435 MonoGame.\u0421\u0435\u0440\u0438\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d\u0430 \u043d\u0430 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u0435\u0439, \u0443\u0436\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b\u0445 \u0441 \u043e\u0441\u043d\u043e\u0432\u0430\u043c\u0438 MonoGame \u0438 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0438.\u0414\u043b\u044f \u043a\u043e\u043c\u0444\u043e\u0440\u0442\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0435\u043c\u0430\u0445:C#MonoGame\u041e\u0441\u043d\u043e\u0432\u044b 3D-\u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u2014 \u043c\u0430\u0442\u0440\u0438\u0446\u044b, \u0432\u0435\u043a\u0442\u043e\u0440\u0430, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f\u041f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043a\u0430\u043c\u0435\u0440\u044b \u0432 3D-\u0441\u0446\u0435\u043d\u0435 \u0438 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0442\u0430\u043a\u043e\u0435 world, view \u0438 projection \u043c\u0430\u0442\u0440\u0438\u0446\u044b\u0411\u0430\u0437\u043e\u0432\u044b\u0439 3D-\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0432 MonoGame (BasicEffect, SkinnedEffect)\u0421\u043a\u0435\u043b\u0435\u0442\u043d\u0430\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f (\u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)\u0415\u0441\u043b\u0438 \u0441 \u0447\u0435\u043c-\u0442\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043f\u0438\u0441\u043a\u0430 \u0432\u044b \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u2014 \u0432 \u0418\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u043e\u0432. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0437\u043d\u0430\u043c\u0435\u043d\u0438\u0442\u044b\u0435 Reimers Tutorials:https:\/\/github.com\/simondarksidej\/XNAGameStudio\/wiki\/RiemersArchiveOverviewDigitalRiseModel\u041d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0432\u0441\u0435\u0439 \u0441\u0435\u0440\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:https:\/\/github.com\/rds1983\/DigitalRiseModel\u042d\u0442\u043e \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 API \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 3D-\u043c\u043e\u0434\u0435\u043b\u044f\u043c\u0438 \u0432 MonoGame.\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442:\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c 3D-\u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b (\u043a\u0443\u0431\u044b, \u0441\u0444\u0435\u0440\u044b, \u043a\u0430\u043f\u0441\u0443\u043b\u044b \u0438 \u0442.\u0434.) \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435\u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0430\u0445 gltf\/glb\u0420\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e \u0441\u043a\u0435\u043b\u0435\u0442\u043d\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439No Content Pipeline\u0422\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Content Pipeline.\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Content Pipeline, \u044f \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043b \u0437\u0434\u0435\u0441\u044c:https:\/\/habr.com\/ru\/articles\/1039344\/\u0412\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0443\u044e \u043c\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443:https:\/\/github.com\/rds1983\/XNAssets\u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 \u00ab\u0441\u044b\u0440\u043e\u043c\u00bb \u0432\u0438\u0434\u0435 \u0431\u0435\u0437 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.\u0427\u0430\u0441\u0442\u044c I\u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0433\u0435\u0440\u043e\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0432\u0438\u0434\u0435 \u043a\u0430\u043f\u0441\u0443\u043b\u044b. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433, \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0438 \u043f\u0440\u044b\u0436\u043a\u0438.\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u043c\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043a\u0430\u043f\u0441\u0443\u043b\u0443 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u043c\u043e\u0434\u0435\u043b\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.\u0422\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 MonoGame-\u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u0434 \u043b\u044e\u0431\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 DesktopGL).\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 NuGet-\u043f\u0430\u043a\u0435\u0442:https:\/\/www.nuget.org\/packages\/DigitalRiseModel.MonoGame\/\u041e\u043d \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u043e\u0434\u0442\u044f\u043d\u0435\u0442 \u0438 XNAssets.\u0421\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u0430\u0440\u0445\u0438\u0432:https:\/\/github.com\/rds1983\/ThirdPersonTutorial\/raw\/refs\/heads\/master\/Step1-Capsule\/Assets.zip\u0417\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u043f\u0430\u043a\u0443\u0439\u0442\u0435 \u0435\u0433\u043e (\u043e\u043d \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u0441\u0435\u0433\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 checker.dds) \u0432 \u043f\u0430\u043f\u043a\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 .csproj \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:&lt;ItemGroup&gt;  &lt;None Update=&#187;Assets\\**\\*.*&#187;&gt;    &lt;CopyToOutputDirectory&gt;PreserveNewest&lt;\/CopyToOutputDirectory&gt;  &lt;\/None&gt;&lt;\/ItemGroup&gt;\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0430\u0441\u0441\u0435\u0442\u044b \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 Output Directory.\u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u044f\u043c\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0430\u0448\u0435\u0433\u043e Game-\u043a\u043b\u0430\u0441\u0441\u0430.\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u0437\u0430\u0434\u0430\u044e\u0449\u0443\u044e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u0432\u044b\u0441\u043e\u0442\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430:\/\/ Hero ground heightprivate const float DefaultY = 1;\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u043b\u044f:\/\/ Stock effect with directional lighting and texturingprivate BasicEffect _basicEffect;\/\/ Ground plane textureprivate Texture2D _textureGround;\/\/ Ground plane meshprivate DrMesh _meshGround;\/\/ Capsule mesh for the playerprivate DrMesh _meshHero;\/\/ Hero position in world spaceprivate Vector3 _heroPosition;DrMesh \u2014 \u044d\u0442\u043e \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 DigitalRiseModel. \u041f\u043e \u0441\u0443\u0442\u0438 \u043e\u043d \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u043e\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e Mesh \u0438\u0437 MonoGame.\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c LoadContent:protected override void LoadContent(){base.LoadContent();\/\/ Load ground texturevar assetManager = AssetManager.CreateFileAssetManager(Path.Combine(AppContext.BaseDirectory, &#171;Assets&#187;));_textureGround = assetManager.LoadTexture2D(GraphicsDevice, &#171;Textures\/checker.dds&#187;);\/\/ Create ground and hero meshes_meshGround = MeshPrimitives.CreatePlaneMesh(GraphicsDevice, uScale: 50, vScale: 50, normalDirection: NormalDirection.UpY);_meshHero = MeshPrimitives.CreateCapsuleMesh(GraphicsDevice);\/\/ Set up rendering effect with lighting_basicEffect = new BasicEffect(GraphicsDevice) { LightingEnabled = true };_basicEffect.DirectionalLight0.Enabled = true;_basicEffect.DirectionalLight0.Direction = new Vector3(-1, -1, -1);_basicEffect.DirectionalLight0.DiffuseColor = Color.White.ToVector3();\/\/ Start hero at world center_heroPosition = new Vector3(0, DefaultY, 0);}\u0417\u0434\u0435\u0441\u044c \u0432\u0441\u0451 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u044f\u043c\u043e\u043b\u0438\u043d\u0435\u0439\u043d\u043e:\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0437\u0435\u043c\u043b\u0438\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0435\u0448 \u0437\u0435\u043c\u043b\u0438\u0441\u043e\u0437\u0434\u0430\u0451\u043c \u043a\u0430\u043f\u0441\u0443\u043b\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430\u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043e\u0441\u0432\u0435\u0449\u0435\u043d\u0438\u0435\u0437\u0430\u0434\u0430\u0451\u043c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0433\u0435\u0440\u043e\u044f\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432: DrawMesh \u0438 ToMatrixDrawMesh\/\/\/ &lt;summary&gt;Render a mesh with color and texture.&lt;\/summary&gt;private void DrawMesh(DrMesh mesh, Matrix world, Color color, Texture2D texture){_basicEffect.DiffuseColor = color.ToVector3();_basicEffect.TextureEnabled = texture != null;_basicEffect.Texture = texture;_basicEffect.World = world;var device = GraphicsDevice;foreach (var part in mesh.MeshParts){device.SetVertexBuffer(part.VertexBuffer);device.Indices = part.IndexBuffer;foreach (EffectPass pass in _basicEffect.CurrentTechnique.Passes){pass.Apply();device.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, part.PrimitiveCount);}}}\u041c\u0435\u0442\u043e\u0434 \u0440\u0438\u0441\u0443\u0435\u0442 \u043c\u0435\u0448 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u043c\u0430\u0442\u0440\u0438\u0446\u043e\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u0446\u0432\u0435\u0442\u043e\u043c \u0438 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439.ToMatrix\/\/\/ &lt;summary&gt;Build transform matrix from position, scale, and rotation (TRS order).&lt;\/summary&gt;private static Matrix ToMatrix(Vector3 position, Vector3 scale, float yaw, float pitch, float roll){var scaleTransform = Matrix.CreateScale(scale);var rotation = Matrix.CreateFromYawPitchRoll(MathHelper.ToRadians(yaw), MathHelper.ToRadians(pitch), MathHelper.ToRadians(roll));var translation = Matrix.CreateTranslation(position);return scaleTransform * rotation * translation;}\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0443\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u0443 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438.\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:Scale -&gt; Rotate -&gt; Translate\u0412 MonoGame\/XNA \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u044e\u0442\u0441\u044f \u0441\u043b\u0435\u0432\u0430 \u043d\u0430\u043f\u0440\u0430\u0432\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u0437\u0430\u0442\u0435\u043c \u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043c\u0438\u0440.Hero, Camera Mount \u0438 Camera\u0421\u0440\u0430\u0437\u0443 \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b \u0432 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u0435.\u041c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e third-person \u043a\u0430\u043c\u0435\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f:\u0412\u0441\u0435\u0433\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0435\u043c\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043c\u044b\u0448\u043a\u043e\u0439 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438\u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043a\u043b\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443 \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437 (\u043a\u0430\u043a \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0433\u0440)\u0414\u0440\u0443\u0433\u0438\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0442\u0430\u043a\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e:\u041e\u043d\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 3 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432:Hero (\u043a\u0430\u043f\u0441\u0443\u043b\u0430) &#8212; \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436Camera Mount \u2014 \u0436\u0451\u0441\u0442\u043a\u0438\u0439 \u201c\u0448\u0442\u0430\u0442\u0438\u0432\u201d, \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u0451\u043d\u043d\u044b\u0439 \u043a \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430. \u0423 \u0435\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u0442\u044c \u0448\u0430\u0440\u043d\u0438\u0440, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0438\u0439 \u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u0432\u0432\u0435\u0440\u0445-\u0432\u043d\u0438\u0437Camera &#8212; \u0441\u0430\u043c\u0430 \u043a\u0430\u043c\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u043a\u043e\u043d\u0446\u0435 \u0448\u0442\u0430\u0442\u0438\u0432\u0430. \u041e\u043d\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0432\u0435\u0440\u043d\u0443\u0442\u0430 \u043d\u0430 180 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432 \u043f\u043e \u043e\u0441\u0438 Y, \u0434\u0430\u0431\u044b \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u043f\u0438\u043d\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430.\u041a\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043b\u0435\u0432\u043e-\u0432\u043f\u0440\u0430\u0432\u043e \u2014 \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0435\u0441\u044c \u0448\u0442\u0430\u0442\u0438\u0432 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u0430\u043c\u0435\u0440\u043e\u0439. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0448\u0442\u0430\u0442\u0438\u0432 \u2014 \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u043a\u043b\u043e\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043d\u0438\u043c, \u043d\u043e \u0441\u0430\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043a\u0440\u0435\u043d\u0438\u0442\u0441\u044f.\u0412\u0441\u044f \u044d\u0442\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0442\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438:\u041f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Hero \u0432 \u043c\u0438\u0440\u0435 (Vector3 _heroPosition)\u0423\u0433\u043e\u043b \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 \u0433\u0435\u0440\u043e\u044f \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u0441\u0438 Y (float _heroYaw)\u0423\u0433\u043e\u043b \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430 Camera Mount \u0432\u043e\u043a\u0440\u0443\u0433 \u043e\u0441\u0438 X (float _cameraMountPitch)\u041f\u0435\u0440\u0432\u0443\u044e \u043c\u044b \u0443\u0436\u0435 \u0437\u0430\u0434\u0430\u043b\u0438. \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435:\/\/ Hero body yaw rotation in degreesprivate float _heroYaw;\/\/ Camera mount pitch rotation in degreesprivate float _cameraMountPitch;\u0412\u0441\u044f \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0435\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439.\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a\u0430\u043c\u0435\u0440\u044b(\u0430 \u043c\u044b \u044d\u0442\u043e\u0433\u043e \u0445\u043e\u0442\u0438\u043c, \u0434\u0430\u0431\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u0443 camera view), \u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0438.\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0441\u0446\u0435\u043d\u044b\u041e\u0431\u044a\u044f\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u043a\u0430\u043c\u0435\u0440\u044b:\/\/ Camera near clipping planeprivate const float NearPlaneDistance = 0.1f;\/\/ Camera far clipping planeprivate const float FarPlaneDistance = 1000.0f;\/\/ Camera field of view in degreesprivate const float ViewAngle = 60.0f;\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c Draw, \u0433\u0434\u0435 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0439:protected override void Draw(GameTime gameTime){base.Draw(gameTime);var device = GraphicsDevice;device.Clear(Color.Black);\/\/ Set GPU statesdevice.DepthStencilState = DepthStencilState.Default;device.RasterizerState = RasterizerState.CullCounterClockwise;device.BlendState = BlendState.AlphaBlend;device.SamplerStates[0] = SamplerState.LinearWrap;\/\/ Set projectionvar projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(ViewAngle),device.Viewport.AspectRatio,NearPlaneDistance, FarPlaneDistance);_basicEffect.Projection = projection;\/\/ Build camera hierarchy: hero body -&gt; camera mount (head) -&gt; cameravar heroTransform = ToMatrix(_heroPosition, Vector3.One, _heroYaw, 0, 0);var cameraMountOffset = new Vector3(0, 1f, 0); \/\/ Camera mount is on the head level &#8212; 1 unit above hero positionvar cameraMountTransform = ToMatrix(cameraMountOffset, Vector3.One, 0, _cameraMountPitch, 0) * heroTransform;var cameraOffset = new Vector3(0, 0, -5); \/\/ Camera is 5 units behind the mountvar cameraTransform = ToMatrix(cameraOffset, Vector3.One, 180, 0, 0) * cameraMountTransform; \/\/ Rotate 180 degrees to look back at the hero_basicEffect.View = Matrix.Invert(cameraTransform);\/\/ Draw ground and heroDrawMesh(_meshGround, Matrix.CreateScale(200, 1, 200), Color.White, _textureGround);DrawMesh(_meshHero, heroTransform, Color.Green, null);}\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 heroTransform. \u0417\u0430\u0442\u0435\u043c \u043d\u0430 \u0435\u0433\u043e \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f cameraMountTransform. \u041e\u043d \u0441\u043c\u0435\u0448\u0451\u043d \u043d\u0430 1 \u043f\u043e \u043e\u0441\u0438 Y(cameraMountOffset), \u0434\u0430\u0431\u044b \u0431\u044b\u0442\u044c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0433\u043e\u043b\u043e\u0432\u044b. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f cameraTransform. \u041e\u043d \u0441\u043c\u0435\u0449\u0435\u043d\u0430 \u043d\u0430 -5 \u043f\u043e \u043e\u0441\u0438 Y \u0438 \u043f\u043e\u0432\u0451\u0440\u043d\u0443\u0442\u0430 \u043d\u0430 180 \u0433\u0440\u0430\u0434\u0443\u0441\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0441\u043f\u0438\u043d\u0443 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430.\u041f\u043e\u0447\u0435\u043c\u0443 View Matrix \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443:_basicEffect.View = Matrix.Invert(cameraTransform);\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c:View Matrix \u2014 \u044d\u0442\u043e \u043d\u0435 transform \u043a\u0430\u043c\u0435\u0440\u044b.\u041d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u044d\u0442\u043e \u043c\u0430\u0442\u0440\u0438\u0446\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u043c\u0438\u0440 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b.\u0418\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438, \u043a\u0430\u043c\u0435\u0440\u0430 \u0432 3D-\u0433\u0440\u0430\u0444\u0438\u043a\u0435 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u00ab\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043c\u0438\u0440\u00bb \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0442\u0435\u043b\u044f.\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f View Matrix \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0438\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0438\u0440\u043e\u0432\u0443\u044e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043a\u0430\u043c\u0435\u0440\u044b.\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u0442\u043e\u0433\u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u0438\u0433\u0440\u0443 \u0441\u0435\u0439\u0447\u0430\u0441, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443:\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0443\u0436\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043e\u0434\u043d\u0430\u043a\u043e \u043a\u0430\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0434\u0432\u0438\u0436\u043d\u043e\u0439.\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u044b\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0443\u044e \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043c\u044b\u0448\u043a\u0438:\/\/ Mouse look sensitivity multiplierprivate const float MouseSensitivity = 0.2f;\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u044b\u0448\u043a\u0438:\/\/ Previous mouse state for delta&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-481323","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481323","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=481323"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481323\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}