{"id":394683,"date":"2024-06-29T11:46:15","date_gmt":"2024-06-29T11:46:15","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=394683"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=394683","title":{"rendered":"<span>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0439 \u0432 \u0438\u0433\u0440\u0435 \u043d\u0430 Unity (\u04271)<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/acc\/16c\/69d\/acc16c69d0a11ac9867554229f8e9f29.png\" width=\"780\" height=\"439\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/acc\/16c\/69d\/acc16c69d0a11ac9867554229f8e9f29.png\"\/><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440 ?<\/p>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0418\u0433\u043e\u0440\u044c, \u0438 \u044f Unity Developer. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0438\u0441\u0441\u0438\u0438 \u0432 \u0438\u0433\u0440\u0435 \u043d\u0430 Unity. \u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u043c\u0438\u0441\u0441\u0438\u0439, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0430 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435. \u041d\u0443 \u0447\u0442\u043e \u0436, \u043f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<h3>\u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0433\u0440\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0433\u0440\u043e\u043a\u0443 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0438, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u043d\u0435\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/de2\/afa\/9ca\/de2afa9caf66d937307d64d45b44133d.png\" alt=\"\u041e\u043a\u043d\u043e \u043c\u0438\u0441\u0441\u0438\u0439\" title=\"\u041e\u043a\u043d\u043e \u043c\u0438\u0441\u0441\u0438\u0439\" width=\"1600\" height=\"789\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/de2\/afa\/9ca\/de2afa9caf66d937307d64d45b44133d.png\"\/><\/p>\n<div><figcaption>\u041e\u043a\u043d\u043e \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p> \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p><em>\u041c\u0438\u0441\u0441\u0438\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0442\u0440\u0435\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438: \u041b\u0415\u0413\u041a\u0410\u042f, \u0421\u0420\u0415\u0414\u041d\u042f\u042f, \u0421\u041b\u041e\u0416\u041d\u0410\u042f<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043c\u0438\u0441\u0441\u0438\u0438<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041a\u043e\u0433\u0434\u0430 \u043c\u0438\u0441\u0441\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u0438\u0433\u0440\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u043e\u043d\u0435\u0442<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0430\u0434\u044b, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u043c\u0438\u0441\u0441\u0438\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0430\u043c\u0438\u0445 \u043c\u0438\u0441\u0441\u0438\u0439, \u0430 \u0437\u0430\u0442\u0435\u043c \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c.<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0439<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0437\u0430\u0434\u0430\u043d\u0438\u044e, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><em>\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u043d\u0430\u0433\u0440\u0430\u0434\u0430<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0438\u043a\u043e\u043d\u043a\u0430<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432 Unity \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 MissionConfig, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043c\u0438\u0441\u0441\u0438\u0438<\/p>\n<pre><code class=\"cs\">public class MissionConfig : ScriptableObject {     [SerializeField] public string id; \/\/\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0438\u0441\u0441\u0438\u0438     [SerializeField] public MissionDifficulty difficulty; \/\/\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c     [SerializeField] public int moneyReward; \/\/\u041d\u0430\u0433\u0440\u0430\u0434\u0430 \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u043d\u0435\u0442     [SerializeField] public string title; \/\/\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438     [SerializeField] public Sprite icon; \/\/\u0418\u043a\u043e\u043d\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0438 }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c enum, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"cs\">public enum MissionDifficulty {     EASY = 0,     NORMAL = 1,     HARD = 2, }<\/code><\/pre>\n<p>\u041d\u0430\u0437\u0440\u0435\u0432\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u0433\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043c <em>&#171;\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c&#187;<\/em> \u0438\u043b\u0438 <em>&#171;\u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0432\u0440\u0430\u0433\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c&#187;<\/em>? \u041e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441-\u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0438:<\/p>\n<pre><code class=\"cs\">\/\/\u041c\u0438\u0441\u0441\u0438\u044f \"\u0421\u043e\u0431\u0440\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b\" [CreateAssetMenu(     fileName = \"CollectResourcesMission\",     menuName = \"Missions\/New CollectResourcesMission\" )] public sealed class CollectResourcesMissionConfig : MissionConfig {     [SerializeField] public ResourceType resourceType; \/\/\u0422\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430 (Enum)     [SerializeField] public int requiredResources; \/\/\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c }   \/\/\u041c\u0438\u0441\u0441\u0438\u044f \"\u0423\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u0432\u0440\u0430\u0433\u043e\u0432\" [CreateAssetMenu(     fileName = \"KillEnemyMission\",     menuName = \"Missions\/New KillEnemyMission\" )] public sealed class KillEnemyMissionConfig : MissionConfig {     [SerializeField] public int requiredKills; \/\/\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0430\u0433\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c }<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c, \u044d\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0432 Unity \u043f\u0440\u043e\u0435\u043a\u0442\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/55a\/e95\/a60\/55ae95a6041159273a3dd6f9b40e8df8.png\" alt=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439 \u0432 Unity\" title=\"\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439 \u0432 Unity\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/55a\/e95\/a60\/55ae95a6041159273a3dd6f9b40e8df8.png\"\/><\/p>\n<div><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439 \u0432 Unity<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0443\u043f\u0435\u0440! \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u0430, \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u0430\u043c\u0438\u0445 \u0437\u0430\u0434\u0430\u043d\u0438\u0439.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u0443\u043c\u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Mission, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u043e\u0431\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0430 \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e: <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/972\/b03\/d24\/972b03d24eab7b6158123cfdc964dfe2.png\" alt=\"\u0421\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u0438\u0441\u0441\u0438\u0439\" title=\"\u0421\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u0438\u0441\u0441\u0438\u0439\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/972\/b03\/d24\/972b03d24eab7b6158123cfdc964dfe2.png\"\/><\/p>\n<div><figcaption>\u0421\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public abstract class Mission {     public event Action&lt;Mission> OnStarted; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0438\u0441\u0441\u0438\u0438     public event Action&lt;Mission> OnCompleted; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438     public event Action&lt;Mission> OnStateChanged; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438      public string Id => this.config.id;     public bool IsCompleted { get; private set; }     public MissionDifficulty Difficulty => this.config.difficulty;     public int MoneyReward => this.config.moneyReward;      public string Title => this.config.title;     public Sprite Icon => this.config.icon;      private readonly MissionConfig config;      public Mission(MissionConfig config)     {         this.config = config;     }      \/\/\u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0438     public void Start()     {         this.OnStarted?.Invoke(this);          if (this.GetProgress() >= 1.0f)         {             this.Complete();             return;         }          this.OnStart();     }          public abstract float GetProgress(); \/\/\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u043e\u0442 0..1     protected abstract void OnStart(); \/\/\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438     protected abstract void OnComplete(); \/\/\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438          \/\/\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f     protected void NotifyAboutStateChanged()     {         if (this.GetProgress() >= 1.0f)         {             this.Complete();         }         else         {             this.OnStateChanged?.Invoke(this);         }     }      private void Complete()     {         this.OnComplete();         this.IsCompleted = true;         this.OnCompleted?.Invoke(this);     } }<\/code><\/pre>\n<p>\u0422\u043e\u0433\u0434\u0430 \u043c\u0438\u0441\u0441\u0438\u044f &#171;\u0414\u043e\u0431\u044b\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b&#187; \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public sealed class CollectResourcesMission : Mission {     private readonly CollectResourcesMissionConfig config;     private readonly Player player;      private int collectedResources;      public CollectResourcesMission(CollectResourcesMissionConfig config)        : base(config)     {         this.config = config;         this.player = Player.Instance; \/\/\u041b\u0443\u0447\u0448\u0435 Dependency Injection \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     }      protected override void OnStart()     {         \/\/\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432         this.player.OnResourcesCollected += this.OnResourcesAdded;     }      protected override void OnComplete()     {         \/\/\u041e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432         this.player.OnResourcesCollected -= this.OnResourcesAdded;     }      protected override float GetProgress()     {         return (float) this.collectedResources \/ this.config.requiredResources;     }      \/\/\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u043b \u0441\u0431\u043e\u0440 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432     private void OnResourcesAdded(ResourceType resourceType, int amount)     {         if (resourceType == this.config.resourceType)         {             this.collectedResources = Math.Min(                 this.collectedResources + amount,                 this.config.requiredResources             );             this.NotifyAboutStateChanged();         }     } }<\/code><\/pre>\n<p>\u0410 \u043c\u0438\u0441\u0441\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430 \u2014 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public sealed class KillEnemyMission : Mission  {     private readonly KillEnemyMissionConfig config;     private readonly Player player;      private int currentKills;      public KillEnemyMission(KillEnemyMissionConfig config) : base(config)     {         this.config = config;         this.player = Player.Instance; \/\/\u041b\u0443\u0447\u0448\u0435 Dependency Injection \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     }      protected override void OnStart()     {         \/\/\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432         this.player.OnEnemyKilled += this.OnEnemyKilled;     }      protected override void OnComplete()     {         \/\/\u041e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432         this.player.OnEnemyKilled -= this.OnEnemyKilled;     }      protected override float GetProgress()     {         return (float) this.currentKills \/ this.config.requiredKills;     }      \/\/\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430     private void OnEnemyKilled()     {         this.currentKills = Math.Min(             this.currentKills + 1,             this.config.requiredKills         );         this.NotifyAboutStateChanged();     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Player. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442\u044c \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432:<\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u0430, \u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0435\u043d\u044c\u0433\u0438: public sealed class Player : MonoBehaviour {     public static Player Instance     {         get         {             if (_instance == null) _instance = FindObjectOfType&lt;Player>();             return _instance;         }     }      private static Player _instance;      public event Action&lt;ResourceType, int> OnResourcesCollected;     public event Action OnEnemyKilled;      \/\/\u041a\u043e\u043b-\u0432\u043e \u0434\u0435\u043d\u0435\u0433 \u0443 \u0438\u0433\u0440\u043e\u043a\u0430:     public int Money { get; set; }      \/\/\u0417\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432     public void CollectResource(ResourceType type, int amount)     {         this.OnResourcesCollected?.Invoke(type, amount);     }          \/\/\u0417\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430     public void KillEnemy()     {         this.OnEnemyKilled?.Invoke();     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b:<\/p>\n<pre><code class=\"cs\">#if UNITY_EDITOR  public sealed class MissionTest : MonoBehaviour {     [SerializeField] private CollectResourcesMissionConfig collectMissionConfig;     [SerializeField] private KillEnemyMissionConfig killMissionConfig;      private Mission collectMission;     private Mission killMission;      private void Start()     {         this.collectMission = new CollectResourcesMission(this.collectMissionConfig);         this.killMission = new KillEnemyMission(this.killMissionConfig);                  this.collectMission.OnStateChanged += this.OnMissionStateChanged;         this.killMission.OnCompleted += this.OnMissionCompleted;         this.collectMission.OnCompleted += this.OnMissionCompleted;         this.killMission.OnStateChanged += this.OnMissionStateChanged;                  this.killMission.Start();         this.collectMission.Start();     }      private void OnMissionCompleted(Mission mission)     {         Debug.Log(mission.Title + \": completed!\");     }      private void OnMissionStateChanged(Mission mission)     {         Debug.Log(mission.Title + \": \" + mission.GetProgress());     }          [ContextMenu(nameof(CollectWood))]     private void CollectWood()     {         Player.Instance.CollectResource(ResourceType.WOOD, 1);     }      [ContextMenu(nameof(KillEnemy))]     private void KillEnemy()     {         Player.Instance.KillEnemy();     } } #endif<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b Player &amp; MissionTest \u043d\u0430 \u0441\u0446\u0435\u043d\u0443 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0439:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f94\/efc\/eba\/f94efceba5046caa2a91bb39d6714e07.png\" alt=\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0438\u0441\u0441\u0438\u0439\" title=\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0438\u0441\u0441\u0438\u0439\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f94\/efc\/eba\/f94efceba5046caa2a91bb39d6714e07.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442! \u041c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \ud83d\ude42<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u044f\u043c\u0438. \u041d\u043e \u043f\u0435\u0440\u0435\u0434 \u044d\u0442\u0438\u043c \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0437\u0430\u0434\u0430\u043d\u0438\u044e:<\/p>\n<ul>\n<li>\n<p><em>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043c\u0438\u0441\u0441\u0438\u0438<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041a\u043e\u0433\u0434\u0430 \u043c\u0438\u0441\u0441\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0438\u0433\u0440\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u043e\u043d\u0435\u0442<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0430\u0434\u044b, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u043c\u0438\u0441\u0441\u0438\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043c\u0438\u0441\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/fb3\/e9d\/0b8\/fb3e9d0b807470ddb709bfcaf3a67802.png\" alt=\"\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439\" title=\"\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439\" width=\"1543\" height=\"471\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/fb3\/e9d\/0b8\/fb3e9d0b807470ddb709bfcaf3a67802.png\"\/><\/p>\n<div><figcaption>\u041e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<blockquote>\n<p>\u0420\u0435\u043c\u0430\u0440\u043a\u0430: \u0412 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u043c\u0438\u0441\u0441\u0438\u0439 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u043d \u0440\u0435\u0448\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447 \u0438 \u043d\u0430\u0440\u0443\u0448\u0430\u0435\u0442 \u043f\u0440\u0438\u043d\u0446\u0438\u043f <em>\u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<\/em><\/p>\n<\/blockquote>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439:<\/p>\n<pre><code class=\"cs\">public sealed class MissionsManager : MonoBehaviour {     public event Action&lt;Mission> OnRewardReceived; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0432\u044b\u0434\u0430\u0447\u0438 \u043d\u0430\u0433\u0440\u0430\u0434\u044b     public event Action&lt;Mission> OnMissionChanged; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438      [SerializeField]      private MissionCatalog catalog; \/\/\u041a\u0430\u0442\u0430\u043b\u043e\u0433 \u0432\u0441\u0435\u0445 \u043c\u0438\u0441\u0441\u0438\u0439 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438      \/\/\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043c\u0438\u0441\u0441\u0438\u0439:     private readonly Dictionary&lt;MissionDifficulty, Mission> missions = new();          private Player player;      private void Awake()     {         this.player = Player.Instance;         this.GenerateMissions();     }      private void Start()     {         foreach (var mission in this.missions.Values)         {             mission.Start();         }     }      public Mission[] GetMissions()     {         return this.missions.Values.ToArray();     }      \/\/\u041c\u0435\u0442\u043e\u0434 \u0432\u044b\u0434\u0430\u0447\u0438 \u043d\u0430\u0433\u0440\u0430\u0434\u044b \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e \u043f\u043e \u043a\u043b\u044e\u0447\u0443:     public void ReceiveReward(MissionDifficulty difficulty)     {         var mission = this.missions[difficulty];         this.ReceiveReward(mission);     }      \/\/\u041c\u0435\u0442\u043e\u0434 \u0432\u044b\u0434\u0430\u0447\u0438 \u043d\u0430\u0433\u0440\u0430\u0434\u044b \u0437\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u043d\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e:     public void ReceiveReward(Mission mission)     {         if (!mission.IsCompleted)         {             throw new Exception($\"Can not receive reward for not completed mission: {mission.Id}!\");         }          this.player.Money += mission.MoneyReward;          this.OnRewardReceived?.Invoke(mission);          var difficulty = mission.Difficulty;         var nextMission = this.GenerateMission(difficulty);         this.OnMissionChanged?.Invoke(nextMission);     }          private void GenerateMissions()     {         for (var d = MissionDifficulty.EASY; d &lt;= MissionDifficulty.HARD; d++)         {             this.GenerateMission(d);         }     }      private Mission GenerateMission(MissionDifficulty difficulty)     {         var missionConfig = this.catalog.RandomMission(difficulty);         var mission = missionConfig.CreateMission();          this.missions[difficulty] = mission;         return mission;     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440, \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u043a\u043b\u0430\u0441\u0441 MissionCatalog, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u043c\u0438\u0441\u0441\u0438\u0439. \u041a\u043e\u0433\u0434\u0430 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0443 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e, \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0431\u0440\u0430\u0442\u044c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e \u0438\u0437 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430:<\/p>\n<pre><code class=\"cs\">[CreateAssetMenu(     fileName = \"MissionCatalog\",     menuName = \"Missions\/New MissionCatalog\" )] public sealed class MissionCatalog : ScriptableObject {     [SerializeField]     public MissionConfig[] missions;      \/\/\u0412\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438:     public MissionConfig RandomMission(MissionDifficulty difficulty)     {         var missions = new List&lt;MissionConfig>();         for (int i = 0, count = this.missions.Length; i &lt; count; i++)         {             var mission = this.missions[i];             if (mission.difficulty == difficulty)             {                 missions.Add(mission);             }         }          var randomIndex = UnityEngine.Random.Range(0, missions.Count);         return missions[randomIndex];     } }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u0440\u0443\u0442\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 MissionConfig \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439 \u0447\u0435\u0440\u0435\u0437 \u043f\u043e\u043b\u0438\u043c\u043e\u0440\u0444\u0438\u0437\u043c:<\/p>\n<pre><code class=\"cs\">public abstract class MissionConfig : ScriptableObject {     [SerializeField] public string id;     [SerializeField] public MissionDifficulty difficulty;     [SerializeField] public int moneyReward;     [SerializeField] public string title;     [SerializeField] public Sprite icon;          public abstract Mission CreateMission(); \/\/\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u043d\u0444\u0438\u0433 \u0441\u0442\u0430\u043b \u0435\u0449\u0435 \u0438 \"\u0444\u0430\u0431\u0440\u0438\u043a\u043e\u0439\": }   public sealed class KillEnemyMissionConfig : MissionConfig {     [SerializeField] public int requiredKills;     public override Mission CreateMission() => new KillEnemyMission(this); }  public sealed class CollectResourcesMissionConfig : MissionConfig {     [SerializeField] public ResourceType resourceType;     [SerializeField] public int requiredResources;     public override Mission CreateMission() => new CollectResourcesMission(this); }<\/code><\/pre>\n<p>\u0418\u0442\u0430\u043a, \u043c\u044b \u043f\u043e\u0447\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u044b \u043a \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e MissionsManager. \u041e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 MissionTest:<\/p>\n<pre><code class=\"cs\">#if UNITY_EDITOR using UnityEngine;  public sealed class MissionTest : MonoBehaviour {     [SerializeField]     private MissionsManager manager;          private void Start()     {         var missions = this.manager.GetMissions();         this.manager.OnMissionChanged += this.OnMissionChanged;         this.manager.OnRewardReceived += this.OnMissionRewardReceived;                  foreach (var mission in missions)         {             Debug.Log($\"{mission.Id}: started\");             mission.OnStateChanged += this.OnMissionStateChanged;             mission.OnCompleted += this.OnMissionCompleted;         }     }      private void OnMissionRewardReceived(Mission mission)     {         Debug.Log($\"{mission.Id}: reward received {mission.MoneyReward}\");     }      private void OnMissionCompleted(Mission mission)     {         mission.OnCompleted -= this.OnMissionCompleted;         mission.OnStateChanged -= this.OnMissionStateChanged;         Debug.Log(mission.Id + \": completed!\");     }      private void OnMissionStateChanged(Mission mission)     {         Debug.Log(mission.Id + \": \" + mission.GetProgress());     }      private void OnMissionChanged(Mission mission)     {         Debug.Log($\"{mission.Id}: started\");         mission.OnStateChanged += this.OnMissionStateChanged;         mission.OnCompleted += this.OnMissionCompleted;     }      [ContextMenu(nameof(CollectWood))]     private void CollectWood()     {         Player.Instance.CollectResource(ResourceType.WOOD, 1);     }      [ContextMenu(nameof(KillEnemy))]     private void KillEnemy()     {         Player.Instance.KillEnemy();     }      [ContextMenu(nameof(ReceiveEasyReward))]     private void ReceiveEasyReward()     {         this.manager.ReceiveReward(MissionDifficulty.EASY);     }          [ContextMenu(nameof(ReceiveNormalReward))]     private void ReceiveNormalReward()     {         this.manager.ReceiveReward(MissionDifficulty.NORMAL);     }          [ContextMenu(nameof(ReceiveHardReward))]     private void ReceiveHardReward()     {         this.manager.ReceiveReward(MissionDifficulty.HARD);     } } #endif<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442 MissionManager \u043d\u0430 \u0441\u0446\u0435\u043d\u0443, \u043f\u043e\u0434\u043a\u044e\u0447\u0430\u0435\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c Play Mode \u0432 Unity:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/0f7\/92c\/bc6\/0f792cbc6b538bbc338498d0afe06557.png\" alt=\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439\" title=\"\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439\" width=\"780\" height=\"440\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/0f7\/92c\/bc6\/0f792cbc6b538bbc338498d0afe06557.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u043f\u043e \u043b\u043e\u0433\u0430\u043c, \u0443\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \ud83d\ude42<\/p>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u043c\u0438\u0441\u0441\u0438\u0439. \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u044e <a href=\"https:\/\/drive.google.com\/file\/d\/13onUcBCFX596W_43TbEEQnYQxJFU_pZv\/view?usp=sharing\">\u0441\u0441\u044b\u043b\u043a\u0443<\/a> \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043f\u043e\u0449\u0443\u043f\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u043c\u0443. \u0410 \u0442\u0430\u043a \u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e\u0431 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0435 \u0434\u043b\u044f \u043c\u0438\u0441\u0441\u0438\u0439. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \ud83d\ude42<\/p>\n<p>\u041d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0445\u043e\u0447\u0443 \u043f\u0440\u0438\u0433\u043b\u0430\u0441\u0438\u0442\u044c \u0432\u0430\u0441 \u043d\u0430 <a href=\"https:\/\/otus.pw\/DIKgJ\/\">\u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0443\u0440\u043e\u043a<\/a>, \u0433\u0434\u0435 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u0438 Unity-\u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438 \u043e \u0442\u043e\u043c, \u0447\u0435\u043c \u043e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f. \u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c \u043a\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 Unity \u0431\u044b\u0432\u0430\u044e\u0442 \u0438 \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0432\u043e\u0439 \u0438\u0433\u0440\u044b. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0440\u044b\u043d\u043e\u043a \u0432\u0430\u043a\u0430\u043d\u0441\u0438\u0439 \u0432 \u0433\u0435\u0439\u043c\u0434\u0435\u0432\u0435 \u0438 \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 \u043e\u043d \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0435\u043c\u044b\u0445 \u0438\u0433\u0440 \u0440\u0430\u0441\u0442\u0451\u0442. \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043e ChatGPT \u0438 \u0441\u043c\u043e\u0436\u0435\u0442 \u043b\u0438 \u043e\u043d \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0438\u0433\u0440 \u043d\u0430 Unity. <\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/otus.pw\/DIKgJ\/\">\u0417\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0439 \u0443\u0440\u043e\u043a<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/739742\/\"> https:\/\/habr.com\/ru\/articles\/739742\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440 ?<\/p>\n<p>\u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0418\u0433\u043e\u0440\u044c, \u0438 \u044f Unity Developer. \u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0438\u0441\u0441\u0438\u0438 \u0432 \u0438\u0433\u0440\u0435 \u043d\u0430 Unity. \u0421\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0434\u043b\u044f \u043c\u0438\u0441\u0441\u0438\u0439, \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u2014 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441, \u0430 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u2014 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435. \u041d\u0443 \u0447\u0442\u043e \u0436, \u043f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<h3>\u0422\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0435<\/h3>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0438\u0433\u0440\u0443, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0433\u0440\u043e\u043a\u0443 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0438, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u043d\u0435\u0442.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041e\u043a\u043d\u043e \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p> \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ul>\n<li>\n<p><em>\u041c\u0438\u0441\u0441\u0438\u0438 \u0431\u044b\u0432\u0430\u044e\u0442 \u0442\u0440\u0435\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438: \u041b\u0415\u0413\u041a\u0410\u042f, \u0421\u0420\u0415\u0414\u041d\u042f\u042f, \u0421\u041b\u041e\u0416\u041d\u0410\u042f<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u043c\u0438\u0441\u0441\u0438\u0438<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041a\u043e\u0433\u0434\u0430 \u043c\u0438\u0441\u0441\u0438\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430, \u0442\u043e \u0438\u0433\u0440\u043e\u043a \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u043d\u0430\u0433\u0440\u0430\u0434\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u043e\u043d\u0435\u0442<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u0433\u0440\u0430\u0434\u044b, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u043c\u0438\u0441\u0441\u0438\u044f \u0442\u043e\u0433\u043e \u0436\u0435 \u0443\u0440\u043e\u0432\u043d\u044f \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0430\u043c\u0438\u0445 \u043c\u0438\u0441\u0441\u0438\u0439, \u0430 \u0437\u0430\u0442\u0435\u043c \u0443\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c.<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0439<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u043c\u0443 \u0437\u0430\u0434\u0430\u043d\u0438\u044e, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0438 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><em>\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u043d\u0430\u0433\u0440\u0430\u0434\u0430<\/em><\/p>\n<\/li>\n<li>\n<p><em>\u0438\u043a\u043e\u043d\u043a\u0430<\/em><\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e\u0431\u044b \u0432 Unity \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439, \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 MissionConfig, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043c\u0438\u0441\u0441\u0438\u0438<\/p>\n<pre><code class=\"cs\">public class MissionConfig : ScriptableObject {     [SerializeField] public string id; \/\/\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u0438\u0441\u0441\u0438\u0438     [SerializeField] public MissionDifficulty difficulty; \/\/\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c     [SerializeField] public int moneyReward; \/\/\u041d\u0430\u0433\u0440\u0430\u0434\u0430 \u0432 \u0432\u0438\u0434\u0435 \u043c\u043e\u043d\u0435\u0442     [SerializeField] public string title; \/\/\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438     [SerializeField] public Sprite icon; \/\/\u0418\u043a\u043e\u043d\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0438 }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c enum, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"cs\">public enum MissionDifficulty {     EASY = 0,     NORMAL = 1,     HARD = 2, }<\/code><\/pre>\n<p>\u041d\u0430\u0437\u0440\u0435\u0432\u0430\u0435\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u0433\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043c <em>&#171;\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c&#187;<\/em> \u0438\u043b\u0438 <em>&#171;\u043a\u0430\u043a\u043e\u0435 \u043a\u043e\u043b-\u0432\u043e \u0432\u0440\u0430\u0433\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c&#187;<\/em>? \u041e\u0442\u0432\u0435\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441-\u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0437\u0430\u0434\u0430\u043d\u0438\u0438:<\/p>\n<pre><code class=\"cs\">\/\/\u041c\u0438\u0441\u0441\u0438\u044f \"\u0421\u043e\u0431\u0440\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b\" [CreateAssetMenu(     fileName = \"CollectResourcesMission\",     menuName = \"Missions\/New CollectResourcesMission\" )] public sealed class CollectResourcesMissionConfig : MissionConfig {     [SerializeField] public ResourceType resourceType; \/\/\u0422\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430 (Enum)     [SerializeField] public int requiredResources; \/\/\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c }   \/\/\u041c\u0438\u0441\u0441\u0438\u044f \"\u0423\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c \u0432\u0440\u0430\u0433\u043e\u0432\" [CreateAssetMenu(     fileName = \"KillEnemyMission\",     menuName = \"Missions\/New KillEnemyMission\" )] public sealed class KillEnemyMissionConfig : MissionConfig {     [SerializeField] public int requiredKills; \/\/\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0430\u0433\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u0442\u044c }<\/code><\/pre>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c, \u044d\u0442\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0438 \u0432 Unity \u043f\u0440\u043e\u0435\u043a\u0442\u0435:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u0438\u0441\u0441\u0438\u0439 \u0432 Unity<\/figcaption><\/div>\n<\/figure>\n<p>\u0421\u0443\u043f\u0435\u0440! \u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u0430, \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u0430\u043c\u0438\u0445 \u0437\u0430\u0434\u0430\u043d\u0438\u0439.<\/p>\n<p>\u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043b\u043e\u0433\u0438\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0437\u0443\u043c\u043d\u0435\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Mission, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0441\u0435\u0431\u0435 \u043e\u0431\u0449\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443, \u0430 \u043a\u043b\u0430\u0441\u0441\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u043e\u0434 \u043a\u0430\u0436\u0434\u0443\u044e \u043c\u0438\u0441\u0441\u0438\u044e: <\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u0435\u043c\u0435\u0439\u0441\u0442\u0432\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public abstract class Mission {     public event Action&lt;Mission> OnStarted; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u0438\u0441\u0441\u0438\u0438     public event Action&lt;Mission> OnCompleted; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438     public event Action&lt;Mission> OnStateChanged; \/\/\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438      public string Id => this.config.id;     public bool IsCompleted { get; private set; }     public MissionDifficulty Difficulty => this.config.difficulty;     public int MoneyReward => this.config.moneyReward;      public string Title => this.config.title;     public Sprite Icon => this.config.icon;      private readonly MissionConfig config;      public Mission(MissionConfig config)     {         this.config = config;     }      \/\/\u041c\u0435\u0442\u043e\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043c\u0438\u0441\u0441\u0438\u0438     public void Start()     {         this.OnStarted?.Invoke(this);          if (this.GetProgress() >= 1.0f)         {             this.Complete();             return;         }          this.OnStart();     }          public abstract float GetProgress(); \/\/\u041f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u043e\u0442 0..1     protected abstract void OnStart(); \/\/\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438     protected abstract void OnComplete(); \/\/\u0417\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0434\u0435\u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043c\u0438\u0441\u0441\u0438\u0438          \/\/\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0438\u0437 \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u043c\u0438\u0441\u0441\u0438\u0438 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f     protected void NotifyAboutStateChanged()     {         if (this.GetProgress() >= 1.0f)         {             this.Complete();         }         else         {             this.OnStateChanged?.Invoke(this);         }     }      private void Complete()     {         this.OnComplete();         this.IsCompleted = true;         this.OnCompleted?.Invoke(this);     } }<\/code><\/pre>\n<p>\u0422\u043e\u0433\u0434\u0430 \u043c\u0438\u0441\u0441\u0438\u044f &#171;\u0414\u043e\u0431\u044b\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b&#187; \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public sealed class CollectResourcesMission : Mission {     private readonly CollectResourcesMissionConfig config;     private readonly Player player;      private int collectedResources;      public CollectResourcesMission(CollectResourcesMissionConfig config)        : base(config)     {         this.config = config;         this.player = Player.Instance; \/\/\u041b\u0443\u0447\u0448\u0435 Dependency Injection \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     }      protected override void OnStart()     {         \/\/\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432         this.player.OnResourcesCollected += this.OnResourcesAdded;     }      protected override void OnComplete()     {         \/\/\u041e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432         this.player.OnResourcesCollected -= this.OnResourcesAdded;     }      protected override float GetProgress()     {         return (float) this.collectedResources \/ this.config.requiredResources;     }      \/\/\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u0435\u043b \u0441\u0431\u043e\u0440 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432     private void OnResourcesAdded(ResourceType resourceType, int amount)     {         if (resourceType == this.config.resourceType)         {             this.collectedResources = Math.Min(                 this.collectedResources + amount,                 this.config.requiredResources             );             this.NotifyAboutStateChanged();         }     } }<\/code><\/pre>\n<p>\u0410 \u043c\u0438\u0441\u0441\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430 \u2014 \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public sealed class KillEnemyMission : Mission  {     private readonly KillEnemyMissionConfig config;     private readonly Player player;      private int currentKills;      public KillEnemyMission(KillEnemyMissionConfig config) : base(config)     {         this.config = config;         this.player = Player.Instance; \/\/\u041b\u0443\u0447\u0448\u0435 Dependency Injection \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     }      protected override void OnStart()     {         \/\/\u041f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432         this.player.OnEnemyKilled += this.OnEnemyKilled;     }      protected override void OnComplete()     {         \/\/\u041e\u0442\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043e\u0442 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432         this.player.OnEnemyKilled -= this.OnEnemyKilled;     }      protected override float GetProgress()     {         return (float) this.currentKills \/ this.config.requiredKills;     }      \/\/\u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0438\u0441\u0441\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430     private void OnEnemyKilled()     {         this.currentKills = Math.Min(             this.currentKills + 1,             this.config.requiredKills         );         this.NotifyAboutStateChanged();     } }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 Player. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0439-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0442\u0440\u0438\u0433\u0433\u0435\u0440\u0438\u0442\u044c \u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u043e\u0432:<\/p>\n<pre><code class=\"cs\">\/\/\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 \u0441\u0438\u043d\u0433\u043b\u0442\u043e\u043d\u0430, \u0433\u0434\u0435 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0434\u0435\u043d\u044c\u0433\u0438: public sealed class Player : MonoBehaviour {     public static Player Instance     {         get         {             if (_instance == null) _instance = FindObjectOfType&lt;Player>();             return _instance;         }     }      private static Player _instance;      public event Action&lt;ResourceType, int> OnResourcesCollected;     public event Action OnEnemyKilled;      \/\/\u041a\u043e\u043b-\u0432\u043e \u0434\u0435\u043d\u0435\u0433 \u0443 \u0438\u0433\u0440\u043e\u043a\u0430:     public int Money { get; set; }      \/\/\u0417\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0431\u043e\u0440\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432     public void CollectResource(ResourceType type, int amount)     {         this.OnResourcesCollected?.Invoke(type, amount);     }          \/\/\u0417\u0430\u0433\u043b\u0443\u0448\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430     public void KillEnemy()     {         this.OnEnemyKilled?.Invoke();     } }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u043a\u0440\u0438\u043f\u0442, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u044b:<\/p>\n<pre><code class=\"cs\">#if UNITY_EDITOR  public sealed class MissionTest : MonoBehaviour {     [SerializeField] private CollectResourcesMissionConfig collectMissionConfig;     [SerializeField] private KillEnemyMissionConfig killMissionConfig;      private Mission collectMission;     private Mission killMission;      private void Start()     {         this.collectMission = new CollectResourcesMission(this.collectMissionConfig);         this.killMission = new KillEnemyMission(this.killMissionConfig);                  this.collectMission.OnStateChanged += this.OnMissionStateChanged;         this.killMission.OnCompleted += this.OnMissionCompleted;         this.collectMission.OnCompleted += this.OnMissionCompleted;         this.killMission.OnStateChanged += this.OnMissionStateChanged;                  this.killMission.Start();         this.collectMission.Start();     }      private void OnMissionCompleted(Mission mission)     {         Debug.Log(mission.Title + \": completed!\");     }      private void OnMissionStateChanged(Mission mission)     {         Debug.Log(mission.Title + \": \" + mission.GetProgress());     }          [ContextMenu(nameof(CollectWood))]     private void CollectWood()     {         Player.Instance.CollectResource(ResourceType.WOOD, 1);     }      [ContextMenu(nameof(KillEnemy))]     private void KillEnemy()     {         Player.Instance.KillEnemy();     } } #endif<\/code><\/pre>\n<p>\u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u044b Player &amp; MissionTest \u043d\u0430 \u0441\u0446\u0435\u043d\u0443 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u043d\u0438\u0439:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u0438 \u043c\u0438\u0441\u0441\u0438\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442! \u041c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \ud83d\ude42<\/p>\n<h3>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u043c\u0438\u0441\u0441\u0438\u0439<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c <\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-394683","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394683","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=394683"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/394683\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=394683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=394683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=394683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}