{"id":273537,"date":"2016-02-03T20:27:02","date_gmt":"2016-02-03T17:27:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=273537"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=273537","title":{"rendered":"\u041f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043a\u0430\u0440\u0442\u044b \u043c\u0438\u0440\u0430 \u043d\u0430 Unity C#, \u0447\u0430\u0441\u0442\u044c 3"},"content":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2a7\/1b8\/0ec\/2a71b80ec9814265bec7783fbdb01cc8.png\" alt=\"image\"\/><\/p>\n<p>  \u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Unity \u0438 C# \u043a\u0430\u0440\u0442\u0430\u0445 \u043c\u0438\u0440\u0430. \u0426\u0438\u043a\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0441\u0442\u0430\u0442\u0435\u0439.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0421\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435<\/p>\n<p>  <a href=\"https:\/\/habrahabr.ru\/post\/276251\/\">\u0427\u0430\u0441\u0442\u044c 1<\/a>:<\/p>\n<p>  \u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0448\u0443\u043c\u0430<br \/>  \u041d\u0430\u0447\u0430\u043b\u043e \u0440\u0430\u0431\u043e\u0442\u044b<br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b \u0432\u044b\u0441\u043e\u0442<\/p>\n<p>  <a href=\"https:\/\/habrahabr.ru\/post\/276281\/\">\u0427\u0430\u0441\u0442\u044c 2<\/a>:<\/p>\n<p>  \u0421\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043e\u0441\u0438<br \/>  \u0421\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u043e\u0431\u0435\u0438\u0445 \u043e\u0441\u044f\u0445<br \/>  \u041f\u043e\u0438\u0441\u043a \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432<br \/>  \u0411\u0438\u0442\u043e\u0432\u044b\u0435 \u043c\u0430\u0441\u043a\u0438<br \/>  \u0417\u0430\u043b\u0438\u0432\u043a\u0430<\/p>\n<p>  \u0427\u0430\u0441\u0442\u044c 3 (\u044d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f):<\/p>\n<p>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b<br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438<br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u043a<\/p>\n<p>  \u0427\u0430\u0441\u0442\u044c 4:<\/p>\n<p>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0438\u043e\u043c\u043e\u0432<br \/>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0444\u0435\u0440\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043a\u0430\u0440\u0442<\/p>\n<p>  <b>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b<\/b><\/p>\n<p>  \u0422\u0435\u043f\u043b\u043e\u0432\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0443 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0438\u0440\u0430. \u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0435\u043c\u0430\u044f \u043d\u0430\u043c\u0438 \u0442\u0435\u043f\u043b\u043e\u0432\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0430 \u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0441\u043e\u0442\u044b \u0438 \u0448\u0438\u0440\u043e\u0442\u044b. \u0414\u0430\u043d\u043d\u044b\u0435 \u0448\u0438\u0440\u043e\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u044b \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043e\u043c \u0448\u0443\u043c\u0430. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 Accidental Noise \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"cs\">ImplicitGradient gradient = new ImplicitGradient (1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1); <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043c\u0438\u0440, \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 \u0442\u0435\u043f\u043b\u0430 \u043d\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 \u043f\u043e \u043e\u0441\u0438 Y.<\/p>\n<p>  \u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043a\u043b\u0430\u0441\u0441 TextureGenerator \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0441 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u043e\u0439:<\/p>\n<pre><code class=\"cs\">public static Texture2D GetHeatMapTexture(int width, int height, Tile[,] tiles) {     var texture = new Texture2D(width, height);     var pixels = new Color[width * height];           for (var x = 0; x &lt; width; x++)     {         for (var y = 0; y &lt; height; y++)         {             pixels[x + y * width] = Color.Lerp(Color.blue, Color.red, tiles[x,y].HeatValue);               \/\/darken the color if a edge tile             if (tiles[x,y].Bitmask != 15)                 pixels[x + y * width] = Color.Lerp(pixels[x + y * width], Color.black, 0.4f);         }     }           texture.SetPixels(pixels);     texture.wrapMode = TextureWrapMode.Clamp;     texture.Apply();     return texture; } <\/code><\/pre>\n<p>  \u041d\u0430\u0448 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/37c\/038\/c80\/37c038c80b5a476fbe5893222bf0665e.png\" alt=\"image\"\/><\/p>\n<p>  \u042d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0442\u0435\u043f\u043b\u0430\u044f \u043f\u043e\u043b\u043e\u0441\u0430 \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u043a\u0430\u0440\u0442\u044b, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430\u044f \u044d\u043a\u0432\u0430\u0442\u043e\u0440\u0443 \u0417\u0435\u043c\u043b\u0438. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043e\u0439 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b, \u043d\u0430\u0434 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u0438 HeatType (\u0442\u0438\u043f\u043e\u0432 \u0442\u0435\u043f\u043b\u0430), \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043d\u0430 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 HeightType (\u0442\u0438\u043f\u043e\u0432 \u0432\u044b\u0441\u043e\u0442) \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438.<\/p>\n<pre><code class=\"cs\">public enum HeatType {     Coldest,     Colder,     Cold,     Warm,     Warmer,     Warmest } <\/code><\/pre>\n<p>  \u042d\u0442\u0438 \u0442\u0438\u043f\u044b \u0442\u0435\u043f\u043b\u0430 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u043c\u0438 \u0438\u0437 Unity inspector \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u043e\u0432\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445:<\/p>\n<pre><code class=\"cs\">float ColdestValue = 0.05f; float ColderValue = 0.18f; float ColdValue = 0.4f; float WarmValue = 0.6f; float WarmerValue = 0.8f; <\/code><\/pre>\n<p>  \u0412 LoadTiles \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0442\u0435\u043f\u043b\u0430 \u043c\u044b \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043c HeatType \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0430\u0439\u043b\u0430.<\/p>\n<pre><code class=\"cs\">\/\/ \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u043c \u0442\u0438\u043f \u0442\u0435\u043f\u043b\u0430 if (heatValue &lt; ColdestValue)      t.HeatType = HeatType.Coldest; else if (heatValue &lt; ColderValue)     t.HeatType = HeatType.Colder; else if (heatValue &lt; ColdValue)      t.HeatType = HeatType.Cold; else if (heatValue &lt; WarmValue)      t.HeatType = HeatType.Warm; else if (heatValue &lt; WarmerValue)      t.HeatType = HeatType.Warmer; else     t.HeatType = HeatType.Warmest; <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043a\u043b\u0430\u0441\u0441 TextureGenerator \u043d\u043e\u0432\u044b\u0435 \u0446\u0432\u0435\u0442\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e HeatType:<\/p>\n<pre><code class=\"cs\">\/\/ \u0426\u0432\u0435\u0442\u0430 \u043a\u0430\u0440\u0442\u044b \u0432\u044b\u0441\u043e\u0442 private static Color Coldest = new Color(0, 1, 1, 1); private static Color Colder = new Color(170\/255f, 1, 1, 1); private static Color Cold = new Color(0, 229\/255f, 133\/255f, 1); private static Color Warm = new Color(1, 1, 100\/255f, 1); private static Color Warmer = new Color(1, 100\/255f, 0, 1); private static Color Warmest = new Color(241\/255f, 12\/255f, 0, 1);   public static Texture2D GetHeatMapTexture(int width, int height, Tile[,] tiles) {     var texture = new Texture2D(width, height);     var pixels = new Color[width * height];           for (var x = 0; x &lt; width; x++)     {         for (var y = 0; y &lt; height; y++)         {             switch (tiles[x,y].HeatType)             {             case HeatType.Coldest:                 pixels[x + y * width] = Coldest;                 break;             case HeatType.Colder:                 pixels[x + y * width] = Colder;                 break;             case HeatType.Cold:                 pixels[x + y * width] = Cold;                 break;             case HeatType.Warm:                 pixels[x + y * width] = Warm;                 break;             case HeatType.Warmer:                 pixels[x + y * width] = Warmer;                 break;             case HeatType.Warmest:                 pixels[x + y * width] = Warmest;                 break;             }                           \/\/\u0437\u0430\u0442\u0435\u043c\u043d\u044f\u0435\u043c \u0446\u0432\u0435\u0442, \u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u043c             if (tiles[x,y].Bitmask != 15)                 pixels[x + y * width] = Color.Lerp(pixels[x + y * width], Color.black, 0.4f);         }     }           texture.SetPixels(pixels);     texture.wrapMode = TextureWrapMode.Clamp;     texture.Apply();     return texture; } <\/code><\/pre>\n<p>  \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044f \u044d\u0442\u0443 \u0442\u0435\u043f\u043b\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0443, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/405\/516\/d47\/405516d476b54268a7a1320f3ef53c1d.png\" alt=\"image\"\/><\/p>\n<p>  \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0447\u0435\u0442\u043a\u043e \u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u043d\u044b\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 HeatType. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043a\u0430 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u043e\u0441\u0430\u043c\u0438. \u041e\u043d\u0438 \u043d\u0435 \u0441\u043e\u043e\u0431\u0449\u0430\u044e\u0442 \u043d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e, \u043a\u0440\u043e\u043c\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0448\u0438\u0440\u043e\u0442\u044b. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0435\u043c\u043f\u0435\u0440\u0430\u0442\u0443\u0440\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u043c\u0435\u0448\u0430\u0435\u043c \u0441 \u044d\u0442\u0438\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043d\u044b\u043c \u0448\u0443\u043c\u043e\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0448\u0443\u043c.<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u043d\u043e\u0432\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438 \u043d\u043e\u0432\u044b\u0439 \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0432 Generator:<\/p>\n<pre><code class=\"cs\">int HeatOctaves = 4; double HeatFrequency = 3.0;     private void Initialize() {     \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0442\u0435\u043f\u043b\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0443     ImplicitGradient gradient  = new ImplicitGradient (1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1);     ImplicitFractal heatFractal = new ImplicitFractal(FractalType.MULTI,                                                        BasisType.SIMPLEX,                                                        InterpolationType.QUINTIC,                                                        HeatOctaves,                                                        HeatFrequency,                                                        Seed);           \/\/ \u041a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u0443\u0435\u043c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u0441 \u0442\u0435\u043f\u043b\u043e\u0432\u044b\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u043e\u043c     HeatMap = new ImplicitCombiner (CombinerType.MULTIPLY);     HeatMap.AddSource (gradient);     HeatMap.AddSource (heatFractal); } <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u0430 \u0441 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f (Multiply) \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0448\u0443\u043c \u0443\u043c\u043d\u043e\u0436\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0448\u0438\u0440\u043e\u0442\u044b. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f Multiply \u043f\u0440\u043e\u0438\u043b\u043b\u044e\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u043d\u0438\u0436\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2a7\/1b8\/0ec\/2a71b80ec9814265bec7783fbdb01cc8.png\" alt=\"image\"\/><\/p>\n<p>  \u0421\u043b\u0435\u0432\u0430 \u2014 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u043d\u044b\u0439 \u0448\u0443\u043c, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u2014 \u0444\u0440\u0430\u043a\u0442\u0430\u043b\u044c\u043d\u044b\u0439 \u0448\u0443\u043c, \u0441\u043f\u0440\u0430\u0432\u0430 \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 Multiply. \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u0442\u0435\u043f\u043b\u043e\u0432\u0430\u044f \u043a\u0430\u0440\u0442\u0430.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0439\u043c\u0435\u043c\u0441\u044f \u0448\u0438\u0440\u043e\u0442\u043e\u0439. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0447\u0435\u0441\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0432\u044b\u0441\u043e\u0442: \u043c\u044b \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0438\u043a\u0438 \u0441\u0430\u043c\u044b\u0445 \u0432\u044b\u0441\u043e\u043a\u0438\u0445 \u0433\u043e\u0440 \u0431\u044b\u043b\u0438 \u0445\u043e\u043b\u043e\u0434\u043d\u044b\u043c\u0438. \u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 LoadTiles:<\/p>\n<pre><code class=\"cs\">\/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u044b\u0441\u043e\u0442\u044b. \u0412\u044b\u0448\u0435 = \u0445\u043e\u043b\u043e\u0434\u043d\u0435\u0435 if (t.HeightType == HeightType.Grass) {     HeatData.Data[t.X, t.Y] -= 0.1f * t.HeightValue; } else if (t.HeightType == HeightType.Forest) {     HeatData.Data[t.X, t.Y] -= 0.2f * t.HeightValue; } else if (t.HeightType == HeightType.Rock) {     HeatData.Data[t.X, t.Y] -= 0.3f * t.HeightValue; } else if (t.HeightType == HeightType.Snow) {     HeatData.Data[t.X, t.Y] -= 0.4f * t.HeightValue; } <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0442\u0435\u043f\u043b\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438 \u0448\u0438\u0440\u043e\u0442\u0430, \u0438 \u0432\u044b\u0441\u043e\u0442\u0430:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/6d4\/678\/c65\/6d4678c651cf4f21bbdfff68ac4b94c6.png\" alt=\"image\"\/><\/p>\n<p>  <b>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438<\/b><\/p>\n<p>  \u041a\u0430\u0440\u0442\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0445\u043e\u0436\u0430 \u043d\u0430 \u0442\u0435\u043f\u043b\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0443. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0444\u0440\u0430\u043a\u0442\u0430\u043b \u0434\u043b\u044f \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043e\u0439 \u0438\u0437 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439. \u0417\u0430\u0442\u0435\u043c \u043c\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b.<\/p>\n<p>  \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043a\u043e\u0434 \u0442\u0435\u043f\u043b\u043e\u0432\u043e\u0439 \u043a\u0430\u0440\u0442\u044b.<\/p>\n<p>  \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u043c \u043a\u043b\u0430\u0441\u0441 Tile \u043d\u043e\u0432\u044b\u043c MoistureType:<\/p>\n<pre><code class=\"cs\">public enum MoistureType {     Wettest,     Wetter,     Wet,     Dry,     Dryer,     Dryest } <\/code><\/pre>\n<p>  \u041a\u043b\u0430\u0441\u0441\u0443 Generator \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0432\u0438\u0434\u0438\u043c\u044b\u0435 \u0438\u0437 Unity Inspector:<\/p>\n<pre><code class=\"cs\">int MoistureOctaves = 4; double MoistureFrequency = 3.0; float DryerValue = 0.27f; float DryValue = 0.4f; float WetValue = 0.6f; float WetterValue = 0.8f; float WettestValue = 0.9f; <\/code><\/pre>\n<p>  \u0412 TextureGenerator \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u043d\u043e\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 (MoistureMap) \u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043d\u0435\u0439 \u0446\u0432\u0435\u0442\u0430:<\/p>\n<pre><code class=\"cs\">\/\/\u041a\u0430\u0440\u0442\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 private static Color Dryest = new Color(255\/255f, 139\/255f, 17\/255f, 1); private static Color Dryer = new Color(245\/255f, 245\/255f, 23\/255f, 1); private static Color Dry = new Color(80\/255f, 255\/255f, 0\/255f, 1); private static Color Wet = new Color(85\/255f, 255\/255f, 255\/255f, 1); private static Color Wetter = new Color(20\/255f, 70\/255f, 255\/255f, 1); private static Color Wettest = new Color(0\/255f, 0\/255f, 100\/255f, 1); <\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"cs\">public static Texture2D GetMoistureMapTexture(int width, int height, Tile[,] tiles) {     var texture = new Texture2D(width, height);     var pixels = new Color[width * height];           for (var x = 0; x &lt; width; x++)     {         for (var y = 0; y &lt; height; y++)         {             Tile t = tiles[x,y];                           if (t.MoistureType == MoistureType.Dryest)                            pixels[x + y * width] = Dryest;             else if (t.MoistureType == MoistureType.Dryer)                           pixels[x + y * width] = Dryer;             else if (t.MoistureType == MoistureType.Dry)                           pixels[x + y * width] = Dry;             else if (t.MoistureType == MoistureType.Wet)                           pixels[x + y * width] = Wet;              else if (t.MoistureType == MoistureType.Wetter)                           pixels[x + y * width] = Wetter;              else                      pixels[x + y * width] = Wettest;          }     }           texture.SetPixels(pixels);     texture.wrapMode = TextureWrapMode.Clamp;     texture.Apply();     return texture; } <\/code><\/pre>\n<p>  \u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0444\u0443\u043d\u043a\u0446\u0438\u044f LoadTiles \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0442\u0438\u043f \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 (MoistureType) \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 (MoistureValue):<\/p>\n<pre><code class=\"cs\">\/\/\u0410\u043d\u0430\u043b\u0438\u0437 \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438   float moistureValue = MoistureData.Data[x,y]; moistureValue = (moistureValue - MoistureData.Min) \/ (MoistureData.Max - MoistureData.Min); t.MoistureValue = moistureValue;   \/\/\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 if (moistureValue &lt; DryerValue) t.MoistureType = MoistureType.Dryest; else if (moistureValue &lt; DryValue) t.MoistureType = MoistureType.Dryer; else if (moistureValue &lt; WetValue) t.MoistureType = MoistureType.Dry; else if (moistureValue &lt; WetterValue) t.MoistureType = MoistureType.Wet; else if (moistureValue &lt; WettestValue) t.MoistureType = MoistureType.Wetter; else t.MoistureType = MoistureType.Wettest; <\/code><\/pre>\n<p>  \u041f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0448\u0443\u043c\u0430 \u0434\u043b\u044f MoistureMap \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/03a\/0ef\/aad\/03a0efaada3740c7bf6b8158fbb1574f.png\" alt=\"image\"\/><\/p>\n<p>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u2014 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043a\u0430\u0440\u0442\u0435 \u0432\u044b\u0441\u043e\u0442. \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 LoadTiles:<\/p>\n<pre><code class=\"cs\">\/\/\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0432\u044b\u0441\u043e\u0442\u0435 if (t.HeightType == HeightType.DeepWater) {     MoistureData.Data[t.X, t.Y] += 8f * t.HeightValue; } else if (t.HeightType == HeightType.ShallowWater) {     MoistureData.Data[t.X, t.Y] += 3f * t.HeightValue; } else if (t.HeightType == HeightType.Shore) {     MoistureData.Data[t.X, t.Y] += 1f * t.HeightValue; } else if (t.HeightType == HeightType.Sand) {     MoistureData.Data[t.X, t.Y] += 0.25f * t.HeightValue; } <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u0430\u0440\u0442\u044b \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u044b\u0441\u043e\u0442\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u0430\u0439\u043b\u043e\u0432 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435: <\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/01d\/f6b\/714\/01df6b71456f487d9ea7ea1df378e259.png\" alt=\"image\"\/><\/p>\n<p>  <b>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u043a<\/b><\/p>\n<p>  \u0421\u043f\u043e\u0441\u043e\u0431 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043e\u043f\u0438\u0448\u0443 \u2014 \u044d\u0442\u043e \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0449\u0438\u0445 \u0440\u0435\u043a \u043f\u0435\u0440\u0435\u0431\u043e\u0440\u043e\u043c.<\/p>\n<p>  \u041f\u0435\u0440\u0432\u044b\u0439 \u0448\u0430\u0433 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u2014 \u0432\u044b\u0431\u043e\u0440 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043b\u0430 \u043d\u0430 \u043a\u0430\u0440\u0442\u0435. \u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0442\u0430\u0439\u043b \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u0443\u0448\u0435\u0439 \u0438 \u0438\u043c\u0435\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0441\u043e\u0442\u044b \u0432\u044b\u0448\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>  \u041d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u044d\u0442\u043e\u0433\u043e \u0442\u0430\u0439\u043b\u0430, \u043c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043a\u0430\u043a\u043e\u0439 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0439 \u0442\u0430\u0439\u043b \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d \u043d\u0438\u0436\u0435 \u0432\u0441\u0435\u0445, \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043d\u0435\u043c\u0443. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0443\u0442\u044c, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0443\u0442 \u0442\u0430\u0439\u043b \u0432\u043e\u0434\u044b.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043d\u0430\u0448\u0438\u043c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u044f\u043c (\u0434\u043b\u0438\u043d\u0430 \u0440\u0435\u043a\u0438, \u0447\u0438\u0441\u043b\u043e \u0438\u0437\u0433\u0438\u0431\u043e\u0432, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0439), \u043c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0438 \u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0435\u0449\u0435 \u0440\u0430\u0437. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435 \u043a\u043e\u0434 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u043d\u0430\u0447\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">private void GenerateRivers() {     int attempts = 0;     int rivercount = RiverCount;     Rivers = new List&lt;River&gt; ();       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u043a\u0438     while (rivercount &gt; 0 && attempts &lt; MaxRiverAttempts) {           \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u0442\u0430\u0439\u043b         int x = UnityEngine.Random.Range (0, Width);         int y = UnityEngine.Random.Range (0, Height);                    Tile tile = Tiles[x,y];           \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0430\u0439\u043b         if (!tile.Collidable) continue;         if (tile.Rivers.Count &gt; 0) continue;           if (tile.HeightValue &gt; MinRiverHeight)         {                            \/\/ \u0422\u0430\u0439\u043b \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u043a\u0438             River river = new River(rivercount);               \/\/ \u0412\u044b\u044f\u0441\u043d\u044f\u0435\u043c, \u0432 \u043a\u0430\u043a\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u0447\u044c \u044d\u0442\u0430 \u0440\u0435\u043a\u0430             river.CurrentDirection = tile.GetLowestNeighbor ();               \/\/ \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043f\u0443\u0442\u044c \u043a \u0432\u043e\u0434\u0435             FindPathToWater(tile, river.CurrentDirection, ref river);               \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0440\u0435\u043a\u0438              if (river.TurnCount &lt; MinRiverTurns || river.Tiles.Count &lt; MinRiverLength || river.Intersections &gt; MaxRiverIntersections)             {                 \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u0430 - \u043e\u0442\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0443 \u0440\u0435\u043a\u0443                 for (int i = 0; i &lt; river.Tiles.Count; i++)                 {                     Tile t = river.Tiles[i];                     t.Rivers.Remove (river);                 }             }             else if (river.Tiles.Count &gt;= MinRiverLength)             {                 \/\/\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u043e\u0439\u0434\u0435\u043d\u0430 - \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0435\u043a\u0443 \u0432 \u0441\u043f\u0438\u0441\u043e\u043a                 Rivers.Add (river);                 tile.Rivers.Add (river);                 rivercount--;                }         }                attempts++;     } } <\/code><\/pre>\n<p>  \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f FindPathToWater() \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0430\u0438\u043b\u0443\u0447\u0448\u0438\u0439 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u044b\u0441\u043e\u0442\u044b \u0441\u0443\u0448\u0438, \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0435\u043a \u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f. \u0420\u0430\u043d\u043e \u0438\u043b\u0438 \u043f\u043e\u0437\u0434\u043d\u043e \u043e\u043d\u0430 \u043d\u0430\u0439\u0434\u0435\u0442 \u0432\u044b\u0445\u043e\u0434 \u043a \u0442\u0430\u0439\u043b\u0443 \u0432\u043e\u0434\u044b. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e, \u043f\u043e\u043a\u0430 \u043f\u0443\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d.<\/p>\n<pre><code class=\"cs\">private void FindPathToWater(Tile tile, Direction direction, ref River river) {     if (tile.Rivers.Contains (river))         return;       \/\/ \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435\u0442 \u043b\u0438 \u0443\u0436\u0435 \u0440\u0435\u043a\u0438 \u043d\u0430 \u044d\u0442\u043e\u043c \u0442\u0430\u0439\u043b\u0435     if (tile.Rivers.Count &gt; 0)         river.Intersections++;       river.AddTile (tile);       \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0435 \u0442\u0430\u0439\u043b\u044b     Tile left = GetLeft (tile);     Tile right = GetRight (tile);     Tile top = GetTop (tile);     Tile bottom = GetBottom (tile);           float leftValue = int.MaxValue;     float rightValue = int.MaxValue;     float topValue = int.MaxValue;     float bottomValue = int.MaxValue;           \/\/ \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0441\u043e\u0442 \u0441\u043e\u0441\u0435\u0434\u0435\u0439     if (left.GetRiverNeighborCount(river) &lt; 2 && !river.Tiles.Contains(left))          leftValue = left.HeightValue;     if (right.GetRiverNeighborCount(river) &lt; 2 && !river.Tiles.Contains(right))          rightValue = right.HeightValue;     if (top.GetRiverNeighborCount(river) &lt; 2 && !river.Tiles.Contains(top))          topValue = top.HeightValue;     if (bottom.GetRiverNeighborCount(river) &lt; 2 && !river.Tiles.Contains(bottom))          bottomValue = bottom.HeightValue;           \/\/ \u0435\u0441\u043b\u0438 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0439 \u0442\u0430\u0439\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0439, \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0439 \u0440\u0435\u043a\u043e\u0439, \u0432\u043b\u0438\u0432\u0430\u0435\u043c\u0441\u044f \u0432 \u043d\u0435\u0435     if (bottom.Rivers.Count == 0 && !bottom.Collidable)         bottomValue = 0;     if (top.Rivers.Count == 0 && !top.Collidable)         topValue = 0;     if (left.Rivers.Count == 0 && !left.Collidable)         leftValue = 0;     if (right.Rivers.Count == 0 && !right.Collidable)         rightValue = 0;           \/\/ \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0442\u043e\u043a, \u0435\u0441\u043b\u0438 \u0442\u0430\u0439\u043b \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0438\u0436\u0435     if (direction == Direction.Left)         if (Mathf.Abs (rightValue - leftValue) &lt; 0.1f)             rightValue = int.MaxValue;     if (direction == Direction.Right)         if (Mathf.Abs (rightValue - leftValue) &lt; 0.1f)             leftValue = int.MaxValue;     if (direction == Direction.Top)         if (Mathf.Abs (topValue - bottomValue) &lt; 0.1f)             bottomValue = int.MaxValue;     if (direction == Direction.Bottom)         if (Mathf.Abs (topValue - bottomValue) &lt; 0.1f)             topValue = int.MaxValue;           \/\/ \u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043c\u0438\u043d\u0438\u043c\u0443\u043c     float min = Mathf.Min (Mathf.Min (Mathf.Min (leftValue, rightValue), topValue), bottomValue);           \/\/ \u0435\u0441\u043b\u0438 \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d - \u0432\u044b\u0445\u043e\u0434     if (min == int.MaxValue)         return;           \/\/\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u043e\u0441\u0435\u0434\u0443     if (min == leftValue) {         if (left.Collidable)         {             if (river.CurrentDirection != Direction.Left){                 river.TurnCount++;                 river.CurrentDirection = Direction.Left;             }             FindPathToWater (left, direction, ref river);         }     } else if (min == rightValue) {         if (right.Collidable)         {             if (river.CurrentDirection != Direction.Right){                 river.TurnCount++;                 river.CurrentDirection = Direction.Right;             }             FindPathToWater (right, direction, ref river);         }     } else if (min == bottomValue) {         if (bottom.Collidable)         {             if (river.CurrentDirection != Direction.Bottom){                 river.TurnCount++;                 river.CurrentDirection = Direction.Bottom;             }             FindPathToWater (bottom, direction, ref river);         }     } else if (min == topValue) {         if (top.Collidable)         {             if (river.CurrentDirection != Direction.Top){                 river.TurnCount++;                 river.CurrentDirection = Direction.Top;             }             FindPathToWater (top, direction, ref river);         }     } } <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0435\u043a \u0443 \u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0443\u0442\u0435\u0439, \u0432\u0435\u0434\u0443\u0449\u0438\u0445 \u043a \u0432\u043e\u0434\u0435. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/631\/0bb\/8bb\/6310bb8bb43e4783be3f975e20f187fe.png\" alt=\"image\"\/> <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/b7c\/4dc\/b96\/b7c4dcb968054259897e2f72f362363b.png\" alt=\"image\"\/><\/p>\n<p>  \u041c\u043d\u043e\u0433\u0438\u0435 \u043f\u0443\u0442\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f, \u0438 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0432\u044b\u0440\u044b\u043b\u0438 \u044d\u0442\u0438 \u0440\u0435\u043a\u0438 \u0441\u0435\u0439\u0447\u0430\u0441, \u043e\u043d\u0438 \u0431\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0438\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u0438 \u0431\u044b \u0432 \u0442\u043e\u0447\u043a\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c, \u043a\u0430\u043a\u0438\u0435 \u0438\u0437 \u0440\u0435\u043a \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f, \u0438 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445.<\/p>\n<p>  \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441 RiverGroup:<\/p>\n<pre><code class=\"cs\">public class RiverGroup {     public List&lt;River&gt; Rivers = new List&lt;River&gt;(); } <\/code><\/pre>\n<p>  \u0410 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u0434, \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0440\u0435\u043a\u0438:<\/p>\n<pre><code class=\"cs\">private void BuildRiverGroups() {     \/\/\u0446\u0438\u043a\u043b\u043e\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u0439\u043b, \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u043b\u0438 \u043e\u043d \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u043c \u0440\u0435\u043a\u0430\u043c     for (var x = 0; x &lt; Width; x++) {         for (var y = 0; y &lt; Height; y++) {             Tile t = Tiles[x,y];               if (t.Rivers.Count &gt; 1)             {                 \/\/ \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u043a == \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435                 RiverGroup group = null;                   \/\/ \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u0443\u0436\u0435 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0433\u0440\u0443\u043f\u043f\u0430 \u0440\u0435\u043a?                 for (int n=0; n &lt; t.Rivers.Count; n++)                 {                     River tileriver = t.Rivers[n];                     for (int i = 0; i &lt; RiverGroups.Count; i++)                     {                         for (int j = 0; j &lt; RiverGroups[i].Rivers.Count; j++)                         {                             River river = RiverGroups[i].Rivers[j];                             if (river.ID == tileriver.ID)                             {                                 group = RiverGroups[i];                             }                             if (group != null) break;                         }                         if (group != null) break;                     }                     if (group != null) break;                 }                   \/\/ \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 -- \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043d\u0435\u0439                 if (group != null)                 {                     for (int n=0; n &lt; t.Rivers.Count; n++)                     {                         if (!group.Rivers.Contains(t.Rivers[n]))                             group.Rivers.Add(t.Rivers[n]);                     }                 }                 else   \/\/\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 -- \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e                 {                     group = new RiverGroup();                     for (int n=0; n &lt; t.Rivers.Count; n++)                     {                         group.Rivers.Add(t.Rivers[n]);                     }                     RiverGroups.Add (group);                 }             }         }     }    } <\/code><\/pre>\n<p>  \u0418\u0442\u0430\u043a, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0430\u044e\u0442\u0441\u044f \u0438 \u0442\u0435\u043a\u0443\u0442 \u043a \u0432\u043e\u0434\u0435. \u041f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0435 \u044d\u0442\u0438\u0445 \u0433\u0440\u0443\u043f\u043f \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u043a\u0430\u0436\u0434\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0430 \u0441\u0432\u043e\u0438\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/fc4\/2de\/193\/fc42de19341547399cca36998005f59f.png\" alt=\"image\"\/><\/p>\n<p>  \u0418\u043c\u0435\u044f \u044d\u0442\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u00ab\u0440\u044b\u0442\u044c\u00bb \u043d\u0430\u0448\u0438 \u0440\u0435\u043a\u0438. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0435\u043a \u043c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 \u0440\u044b\u0442\u044c\u044f \u0441\u0430\u043c\u043e\u0439 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 \u0440\u0435\u043a\u0438 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435. \u041e\u0441\u0442\u0430\u0432\u0448\u0438\u0435\u0441\u044f \u0440\u0435\u043a\u0438 \u0440\u043e\u044e\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u043b\u0438\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438.<\/p>\n<p>  \u041a\u043e\u0434 \u043d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043a\u0430\u043a \u043c\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0440\u044b\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u044b \u0440\u0435\u043a:<\/p>\n<pre><code class=\"cs\">private void DigRiverGroups() {     for (int i = 0; i &lt; RiverGroups.Count; i++) {           RiverGroup group = RiverGroups[i];         River longest = null;           \/\/\u041f\u043e\u0438\u0441\u043a \u0441\u0430\u043c\u043e\u0439 \u0434\u043b\u0438\u043d\u043d\u043e\u0439 \u0440\u0435\u043a\u0438 \u0432 \u044d\u0442\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435         for (int j = 0; j &lt; group.Rivers.Count; j++)         {             River river = group.Rivers[j];             if (longest == null)                 longest = river;             else if (longest.Tiles.Count &lt; river.Tiles.Count)                 longest = river;         }           if (longest != null)         {                            \/\/\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u043e\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u0434\u043b\u0438\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c             DigRiver (longest);               for (int j = 0; j &lt; group.Rivers.Count; j++)             {                 River river = group.Rivers[j];                 if (river != longest)                 {                     DigRiver (river, longest);                 }             }         }     } } <\/code><\/pre>\n<p>  \u041a\u043e\u0434 \u0440\u044b\u0442\u044c\u044f \u0440\u0435\u043a\u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u043d\u0434\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u0432\u0430\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u043a\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u043b\u0430\u0441\u044c \u043f\u0440\u0438 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0438 \u043a \u0432\u043e\u0434\u0435. \u041a\u043e\u0434 DigRiver() \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043a\u0440\u0430\u0441\u0438\u0432, \u043d\u043e \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441 \u0437\u0430\u0434\u0430\u0447\u0435\u0439:<\/p>\n<pre><code class=\"cs\">private void DigRiver(River river) {     int counter = 0;           \/\/ \u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0438\u0440\u043e\u043a\u0430 \u0431\u0443\u0434\u0435\u0442 \u044d\u0442\u0430 \u0440\u0435\u043a\u0430?     int size = UnityEngine.Random.Range(1,5);     river.Length = river.Tiles.Count;         \/\/ \u0440\u0430\u043d\u0434\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430     int two = river.Length \/ 2;     int three = two \/ 2;     int four = three \/ 2;     int five = four \/ 2;           int twomin = two \/ 3;     int threemin = three \/ 3;     int fourmin = four \/ 3;     int fivemin = five \/ 3;       \/\/ \u0440\u0430\u043d\u0434\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0434\u043b\u0438\u043d\u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430     int count1 = UnityEngine.Random.Range (fivemin, five);                  if (size &lt; 4) {         count1 = 0;     }     int count2 = count1 + UnityEngine.Random.Range(fourmin, four);      if (size &lt; 3) {         count2 = 0;         count1 = 0;     }     int count3 = count2 + UnityEngine.Random.Range(threemin, three);      if (size &lt; 2) {         count3 = 0;         count2 = 0;         count1 = 0;     }     int count4 = count3 + UnityEngine.Random.Range (twomin, two);             \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u043d\u0435 \u0440\u043e\u0435\u043c \u043c\u044b \u0443\u0436\u0435 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0438 \u0440\u0435\u043a\u0438     if (count4 &gt; river.Length) {         int extra = count4 - river.Length;         while (extra &gt; 0)         {             if (count1 &gt; 0) { count1--; count2--; count3--; count4--; extra--; }             else if (count2 &gt; 0) { count2--; count3--; count4--; extra--; }             else if (count3 &gt; 0) { count3--; count4--; extra--; }             else if (count4 &gt; 0) { count4--; extra--; }         }     }       \/\/ \u0420\u043e\u0435\u043c \u0440\u0435\u043a\u0443     for (int i = river.Tiles.Count - 1; i &gt;= 0 ; i--)     {         Tile t = river.Tiles[i];           if (counter &lt; count1) {             t.DigRiver (river, 4);                       }         else if (counter &lt; count2) {             t.DigRiver (river, 3);                       }          else if (counter &lt; count3) {             t.DigRiver (river, 2);                       }          else if ( counter &lt; count4) {             t.DigRiver (river, 1);         }         else {             t.DigRiver(river, 0);         }                    counter++;               } } <\/code><\/pre>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u0440\u044b\u0442\u044c\u044f \u0440\u0435\u043a \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0435\u0447\u0442\u043e \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0435:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/947\/25d\/6bd\/94725d6bd17c494bbd66b7f714d36f26.png\" alt=\"image\"\/><\/p>\n<p>  \u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0449\u0438\u0435 \u0440\u0435\u043a\u0438, \u043e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u043e\u043d\u0438 \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u044e\u0442 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u0430\u0440\u0442\u044b. \u0420\u0435\u043a\u0438 \u043d\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0443\u0441\u0442\u044b\u043d\u043d\u044b\u0445 \u043e\u0431\u043b\u0430\u0441\u0442\u044f\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u043e\u043a\u0440\u0443\u0433 \u0440\u0435\u043a \u0441\u0443\u0445\u043e\u0439.<\/p>\n<p>  \u0414\u043b\u044f \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043a\u0430\u0440\u0442\u0443 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043e \u0440\u0435\u043a\u0430\u0445.<\/p>\n<pre><code class=\"cs\">private void AdjustMoistureMap() {     for (var x = 0; x &lt; Width; x++) {         for (var y = 0; y &lt; Height; y++) {               Tile t = Tiles[x,y];             if (t.HeightType == HeightType.River)             {                 AddMoisture (t, (int)60);             }         }     } } <\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043b\u0430. \u0427\u0435\u043c \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u0442 \u0440\u0435\u043a\u0438, \u0442\u0435\u043c \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0442\u0430\u0439\u043b.<\/p>\n<pre><code class=\"cs\">private void AddMoisture(Tile t, int radius) {     int startx = MathHelper.Mod (t.X - radius, Width);     int endx = MathHelper.Mod (t.X + radius, Width);     Vector2 center = new Vector2(t.X, t.Y);     int curr = radius;       while (curr &gt; 0) {           int x1 = MathHelper.Mod (t.X - curr, Width);         int x2 = MathHelper.Mod (t.X + curr, Width);         int y = t.Y;           AddMoisture(Tiles[x1, y], 0.025f \/ (center - new Vector2(x1, y)).magnitude);           for (int i = 0; i &lt; curr; i++)         {             AddMoisture (Tiles[x1, MathHelper.Mod (y + i + 1, Height)], 0.025f \/ (center - new Vector2(x1, MathHelper.Mod (y + i + 1, Height))).magnitude);             AddMoisture (Tiles[x1, MathHelper.Mod (y - (i + 1), Height)], 0.025f \/ (center - new Vector2(x1, MathHelper.Mod (y - (i + 1), Height))).magnitude);               AddMoisture (Tiles[x2, MathHelper.Mod (y + i + 1, Height)], 0.025f \/ (center - new Vector2(x2, MathHelper.Mod (y + i + 1, Height))).magnitude);             AddMoisture (Tiles[x2, MathHelper.Mod (y - (i + 1), Height)], 0.025f \/ (center - new Vector2(x2, MathHelper.Mod (y - (i + 1), Height))).magnitude);         }         curr--;     } } <\/code><\/pre>\n<p>  \u0422\u0430\u043a\u0430\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u0430\u0440\u0442\u0443 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0440\u0435\u043a. \u041e\u043d\u0430 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0431\u0438\u043e\u043c\u044b.<\/p>\n<p>  \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u0432\u043b\u0430\u0436\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/4bf\/c71\/c83\/4bfc71c8305a4eb6aae6fc602e5a7ec4.png\" alt=\"image\"\/>       <\/p>\n<div class=\"clear\"><\/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:\/\/habrahabr.ru\/post\/276533\/\"> https:\/\/habrahabr.ru\/post\/276533\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2a7\/1b8\/0ec\/2a71b80ec9814265bec7783fbdb01cc8.png\" alt=\"image\"\/><\/p>\n<p>  \u042d\u0442\u043e \u0442\u0440\u0435\u0442\u044c\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043e \u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u044b\u0445 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Unity \u0438 C# \u043a\u0430\u0440\u0442\u0430\u0445 \u043c\u0438\u0440\u0430. \u0426\u0438\u043a\u043b \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0447\u0435\u0442\u044b\u0440\u0435\u0445 \u0441\u0442\u0430\u0442\u0435\u0439.  <\/p>\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-273537","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273537","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=273537"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/273537\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=273537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=273537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=273537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}