.gdpr{position: fixed; top: 0; bottom: 0; left: 0; right: 0; background: rgba(0, 0, 0, 0.7);color: #333;z-index:9999999;line-height:1.3;height: 100vh;width: 100vw} .gdpr_w{padding: 2rem;background: #fff;max-width: 700px;width: 95%;margin: 5% auto;text-align: center;position:fixed;left: 0;right: 0;margin:10% auto;} .gdpr_t{margin-bottom:15px;} .gdpr_t h3{font-size: 30px;margin:0px 0 10px 0;} .gdpr_t p{font-size: 16px;line-height: 1.45;margin:0;} .gdpr_x {position: absolute; right: 24px; top: 16px; cursor:pointer;} .gdpr_yn{margin-top:10px;} .gdpr_yn form{display: inline;} .gdpr_yn button{background: #37474F;border: none;color: #fff;padding: 8px 30px;font-size: 13px;margin: 0 3px;} .gdpr_yn .gdpr_n{background: #fff;color: #222;border: 1px solid #999;} amp-consent{margin-left: 10px;top: 2px;width: auto;background: transparent;} .gdpr_fmi{ width:100%; font-size: 15px; line-height: 1.45; margin: 0; } #footer .gdpr_fmi span, .gdpr_fmi span { display: inline-block; } #footer .gdpr_fmi a{ color: #005be2; } @media(max-width:768px){ .gdpr_w{width: 85%;margin:0 auto;padding:1.5rem;} } @media(max-width:700px){ .gdpr_w{margin:0 auto; width: 85%;} } .gdpr_fmi a:before{ display:none; } .gdpr_w{width:100%;} .f-w-f2 { padding: 50px 0px; } footer amp-consent.amp-active { z-index:9999; display: initial; position: inherit; height:20px; width:100%; } body[class*="amp-iso-country-"] .amp-active{ display: contents; } #post-consent-ui { position: fixed; z-index: 9999; left: 45%; margin-top: 10px; top: 0; } @font-face { font-family: Poppins;font-display: optional;font-style: normal;font-weight: 400;src: local('Poppins Regular '), local('Poppins-Regular'), url(https://fonts.gstatic.com/s/poppins/v13/pxiEyp8kv8JHgFVrFJDUc1NECPY.ttf);}@font-face { font-family: Poppins;font-display: optional;font-style: normal;font-weight: 500;src: local('Poppins Medium '), local('Poppins-Medium'), url(https://fonts.gstatic.com/s/poppins/v13/pxiByp8kv8JHgFVrLGT9V1tvFP-KUEg.ttf);}@font-face { font-family: Poppins;font-display: optional;font-style: normal;font-weight: 700;src: local('Poppins Bold '), local('Poppins-Bold'), url(https://fonts.gstatic.com/s/poppins/v13/pxiByp8kv8JHgFVrLCz7V1tvFP-KUEg.ttf);}a.heateor_sss_amp{padding:0 4px}div.heateor_sss_horizontal_sharing a amp-img{display:inline-block}.heateor_sss_amp_instagram img{background-color:#624E47}.heateor_sss_amp_yummly img{background-color:#E16120}.heateor_sss_amp_youtube img{background-color:#ff0000}.heateor_sss_amp_buffer img{background-color:#000}.heateor_sss_amp_delicious img{background-color:#53BEEE}.heateor_sss_amp_facebook img{background-color:#3C589A}.heateor_sss_amp_digg img{background-color:#006094}.heateor_sss_amp_email img{background-color:#649A3F}.heateor_sss_amp_float_it img{background-color:#53BEEE}.heateor_sss_amp_linkedin img{background-color:#0077B5}.heateor_sss_amp_pinterest img{background-color:#CC2329}.heateor_sss_amp_print img{background-color:#FD6500}.heateor_sss_amp_reddit img{background-color:#FF5700}.heateor_sss_amp_stocktwits img{background-color:#40576F}.heateor_sss_amp_mewe img{background-color:#007da1}.heateor_sss_amp_mix img{background-color:#ff8226}.heateor_sss_amp_tumblr img{background-color:#29435D}.heateor_sss_amp_twitter img{background-color:#55acee}.heateor_sss_amp_vkontakte img{background-color:#5E84AC}.heateor_sss_amp_yahoo img{background-color:#8F03CC}.heateor_sss_amp_xing img{background-color:#00797D}.heateor_sss_amp_instagram img{background-color:#527FA4}.heateor_sss_amp_whatsapp img{background-color:#55EB4C}.heateor_sss_amp_aim img{background-color:#10ff00}.heateor_sss_amp_amazon_wish_list img{background-color:#ffe000}.heateor_sss_amp_aol_mail img{background-color:#2A2A2A}.heateor_sss_amp_app_net img{background-color:#5D5D5D}.heateor_sss_amp_baidu img{background-color:#2319DC}.heateor_sss_amp_balatarin img{background-color:#fff}.heateor_sss_amp_bibsonomy img{background-color:#000}.heateor_sss_amp_bitty_browser img{background-color:#EFEFEF}.heateor_sss_amp_blinklist img{background-color:#3D3C3B}.heateor_sss_amp_blogger_post img{background-color:#FDA352}.heateor_sss_amp_blogmarks img{background-color:#535353}.heateor_sss_amp_bookmarks_fr img{background-color:#E8EAD4}.heateor_sss_amp_box_net img{background-color:#1A74B0}.heateor_sss_amp_buddymarks img{background-color:#ffd400}.heateor_sss_amp_care2_news img{background-color:#6EB43F}.heateor_sss_amp_citeulike img{background-color:#2781CD}.heateor_sss_amp_comment img{background-color:#444}.heateor_sss_amp_diary_ru img{background-color:#E8D8C6}.heateor_sss_amp_diaspora img{background-color:#2E3436}.heateor_sss_amp_dihitt img{background-color:#FF6300}.heateor_sss_amp_diigo img{background-color:#4A8BCA}.heateor_sss_amp_douban img{background-color:#497700}.heateor_sss_amp_draugiem img{background-color:#ffad66}.heateor_sss_amp_dzone img{background-color:#fff088}.heateor_sss_amp_evernote img{background-color:#8BE056}.heateor_sss_amp_facebook_messenger img{background-color:#0084FF}.heateor_sss_amp_fark img{background-color:#555}.heateor_sss_amp_fintel img{background-color:#087515}.heateor_sss_amp_flipboard img{background-color:#CC0000}.heateor_sss_amp_folkd img{background-color:#0F70B2}.heateor_sss_amp_google_classroom img{background-color:#FFC112}.heateor_sss_amp_google_bookmarks img{background-color:#CB0909}.heateor_sss_amp_google_gmail img{background-color:#E5E5E5}.heateor_sss_amp_hacker_news img{background-color:#F60}.heateor_sss_amp_hatena img{background-color:#00A6DB}.heateor_sss_amp_instapaper img{background-color:#EDEDED}.heateor_sss_amp_jamespot img{background-color:#FF9E2C}.heateor_sss_amp_kakao img{background-color:#FCB700}.heateor_sss_amp_kik img{background-color:#2A2A2A}.heateor_sss_amp_kindle_it img{background-color:#2A2A2A}.heateor_sss_amp_known img{background-color:#fff101}.heateor_sss_amp_line img{background-color:#00C300}.heateor_sss_amp_livejournal img{background-color:#EDEDED}.heateor_sss_amp_mail_ru img{background-color:#356FAC}.heateor_sss_amp_mendeley img{background-color:#A70805}.heateor_sss_amp_meneame img{background-color:#FF7D12}.heateor_sss_amp_mixi img{background-color:#EDEDED}.heateor_sss_amp_myspace img{background-color:#2A2A2A}.heateor_sss_amp_netlog img{background-color:#2A2A2A}.heateor_sss_amp_netvouz img{background-color:#c0ff00}.heateor_sss_amp_newsvine img{background-color:#055D00}.heateor_sss_amp_nujij img{background-color:#D40000}.heateor_sss_amp_odnoklassniki img{background-color:#F2720C}.heateor_sss_amp_oknotizie img{background-color:#fdff88}.heateor_sss_amp_outlook_com img{background-color:#0072C6}.heateor_sss_amp_papaly img{background-color:#3AC0F6}.heateor_sss_amp_pinboard img{background-color:#1341DE}.heateor_sss_amp_plurk img{background-color:#CF682F}.heateor_sss_amp_pocket img{background-color:#f0f0f0}.heateor_sss_amp_polyvore img{background-color:#2A2A2A}.heateor_sss_amp_printfriendly img{background-color:#61D1D5}.heateor_sss_amp_protopage_bookmarks img{background-color:#413FFF}.heateor_sss_amp_pusha img{background-color:#0072B8}.heateor_sss_amp_qzone img{background-color:#2B82D9}.heateor_sss_amp_refind img{background-color:#1492ef}.heateor_sss_amp_rediff_mypage img{background-color:#D20000}.heateor_sss_amp_renren img{background-color:#005EAC}.heateor_sss_amp_segnalo img{background-color:#fdff88}.heateor_sss_amp_sina_weibo img{background-color:#ff0}.heateor_sss_amp_sitejot img{background-color:#ffc800}.heateor_sss_amp_skype img{background-color:#00AFF0}.heateor_sss_amp_sms img{background-color:#6ebe45}.heateor_sss_amp_slashdot img{background-color:#004242}.heateor_sss_amp_stumpedia img{background-color:#EDEDED}.heateor_sss_amp_svejo img{background-color:#fa7aa3}.heateor_sss_amp_symbaloo_feeds img{background-color:#6DA8F7}.heateor_sss_amp_telegram img{background-color:#3DA5f1}.heateor_sss_amp_trello img{background-color:#1189CE}.heateor_sss_amp_tuenti img{background-color:#0075C9}.heateor_sss_amp_twiddla img{background-color:#EDEDED}.heateor_sss_amp_typepad_post img{background-color:#2A2A2A}.heateor_sss_amp_viadeo img{background-color:#2A2A2A}.heateor_sss_amp_viber img{background-color:#8B628F}.heateor_sss_amp_wanelo img{background-color:#fff}.heateor_sss_amp_webnews img{background-color:#CC2512}.heateor_sss_amp_wordpress img{background-color:#464646}.heateor_sss_amp_wykop img{background-color:#367DA9}.heateor_sss_amp_yahoo_mail img{background-color:#400090}.heateor_sss_amp_yahoo_messenger img{background-color:#400090}.heateor_sss_amp_yoolink img{background-color:#A2C538}.heateor_sss_amp_youmob img{background-color:#3B599D}.heateor_sss_amp_gentlereader img{background-color:#46aecf}.heateor_sss_amp_threema img{background-color:#2A2A2A}.heateor_sss_vertical_sharing{position:fixed;left:11px;z-index:99999}.heateor-total-share-count .sss_share_count{color:#666;font-size:23px}.heateor-total-share-count .sss_share_lbl{color:#666}.amp-wp-enforced-sizes img[alt="Pinterest"]{background:#cc2329}.amp-wp-enforced-sizes img[alt="Viber"]{background:#8b628f}.amp-wp-enforced-sizes img[alt="Print"]{background:#fd6500}.amp-wp-enforced-sizes img[alt="Threema"]{background:#2a2a2a}.amp-wp-article-content .heateor_sss_vertical_sharing{left:5px}.amp-wp-article-content amp-img[alt="Pinterest"]{left:4px}.amp-wp-enforced-sizes img[alt="MySpace"]{background:#2a2a2a} amp-web-push-widget button.amp-subscribe { display: inline-flex; align-items: center; border-radius: 5px; border: 0; box-sizing: border-box; margin: 0; padding: 10px 15px; cursor: pointer; outline: none; font-size: 15px; font-weight: 500; background: #4A90E2; margin-top: 7px; color: white; box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.5); -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } a.heateor_sss_amp{padding:0 4px;}div.heateor_sss_horizontal_sharing a amp-img{display:inline-block;}.heateor_sss_amp_gab img{background-color:#25CC80}.heateor_sss_amp_parler img{background-color:#892E5E}.heateor_sss_amp_gettr img{background-color:#E50000}.heateor_sss_amp_instagram img{background-color:#624E47}.heateor_sss_amp_yummly img{background-color:#E16120}.heateor_sss_amp_youtube img{background-color:#ff0000}.heateor_sss_amp_teams img{background-color:#5059c9}.heateor_sss_amp_google_translate img{background-color:#528ff5}.heateor_sss_amp_x img{background-color:#2a2a2a}.heateor_sss_amp_rutube img{background-color:#14191f}.heateor_sss_amp_buffer img{background-color:#000}.heateor_sss_amp_delicious img{background-color:#53BEEE}.heateor_sss_amp_rss img{background-color:#e3702d}.heateor_sss_amp_facebook img{background-color:#0765FE}.heateor_sss_amp_perplexity img{background-color:#165962}.heateor_sss_amp_claude img{background-color:#D97757}.heateor_sss_amp_google_ai img{background-color:#000}.heateor_sss_amp_grok img{background-color:#000}.heateor_sss_amp_chatgpt img{background-color:#000}.heateor_sss_amp_digg img{background-color:#006094}.heateor_sss_amp_email img{background-color:#649A3F}.heateor_sss_amp_float_it img{background-color:#53BEEE}.heateor_sss_amp_linkedin img{background-color:#0077B5}.heateor_sss_amp_pinterest img{background-color:#CC2329}.heateor_sss_amp_print img{background-color:#FD6500}.heateor_sss_amp_reddit img{background-color:#FF5700}.heateor_sss_amp_mastodon img{background-color:#6364FF}.heateor_sss_amp_stocktwits img{background-color: #40576F}.heateor_sss_amp_mewe img{background-color:#007da1}.heateor_sss_amp_mix img{background-color:#ff8226}.heateor_sss_amp_tumblr img{background-color:#29435D}.heateor_sss_amp_twitter img{background-color:#55acee}.heateor_sss_amp_vkontakte img{background-color:#0077FF}.heateor_sss_amp_yahoo img{background-color:#8F03CC}.heateor_sss_amp_xing img{background-color:#00797D}.heateor_sss_amp_instagram img{background-color:#527FA4}.heateor_sss_amp_whatsapp img{background-color:#55EB4C}.heateor_sss_amp_aim img{background-color: #10ff00}.heateor_sss_amp_amazon_wish_list img{background-color: #ffe000}.heateor_sss_amp_aol_mail img{background-color: #2A2A2A}.heateor_sss_amp_app_net img{background-color: #5D5D5D}.heateor_sss_amp_balatarin img{background-color: #fff}.heateor_sss_amp_bibsonomy img{background-color: #000}.heateor_sss_amp_bitty_browser img{background-color: #EFEFEF}.heateor_sss_amp_blinklist img{background-color: #3D3C3B}.heateor_sss_amp_blogger_post img{background-color: #FDA352}.heateor_sss_amp_blogmarks img{background-color: #535353}.heateor_sss_amp_bookmarks_fr img{background-color: #E8EAD4}.heateor_sss_amp_box_net img{background-color: #1A74B0}.heateor_sss_amp_buddymarks img{background-color: #ffd400}.heateor_sss_amp_care2_news img{background-color: #6EB43F}.heateor_sss_amp_comment img{background-color: #444}.heateor_sss_amp_diary_ru img{background-color: #E8D8C6}.heateor_sss_amp_diaspora img{background-color: #2E3436}.heateor_sss_amp_dihitt img{background-color: #FF6300}.heateor_sss_amp_diigo img{background-color: #4A8BCA}.heateor_sss_amp_douban img{background-color: #497700}.heateor_sss_amp_draugiem img{background-color: #ffad66}.heateor_sss_amp_evernote img{background-color: #8BE056}.heateor_sss_amp_facebook_messenger img{background-color: #0084FF}.heateor_sss_amp_fark img{background-color: #555}.heateor_sss_amp_fintel img{background-color: #087515}.heateor_sss_amp_flipboard img{background-color: #CC0000}.heateor_sss_amp_folkd img{background-color: #0F70B2}.heateor_sss_amp_google_news img{background-color: #4285F4}.heateor_sss_amp_google_classroom img{background-color: #FFC112}.heateor_sss_amp_google_gmail img{background-color: #E5E5E5}.heateor_sss_amp_hacker_news img{background-color: #F60}.heateor_sss_amp_hatena img{background-color: #00A6DB}.heateor_sss_amp_instapaper img{background-color: #EDEDED}.heateor_sss_amp_jamespot img{background-color: #FF9E2C}.heateor_sss_amp_kakao img{background-color: #FCB700}.heateor_sss_amp_kik img{background-color: #2A2A2A}.heateor_sss_amp_kindle_it img{background-color: #2A2A2A}.heateor_sss_amp_known img{background-color: #fff101}.heateor_sss_amp_line img{background-color: #00C300}.heateor_sss_amp_livejournal img{background-color: #EDEDED}.heateor_sss_amp_mail_ru img{background-color: #356FAC}.heateor_sss_amp_mendeley img{background-color: #A70805}.heateor_sss_amp_meneame img{background-color: #FF7D12}.heateor_sss_amp_mixi img{background-color: #EDEDED}.heateor_sss_amp_myspace img{background-color: #2A2A2A}.heateor_sss_amp_netlog img{background-color: #2A2A2A}.heateor_sss_amp_netvouz img{background-color: #c0ff00}.heateor_sss_amp_newsvine img{background-color: #055D00}.heateor_sss_amp_nujij img{background-color: #D40000}.heateor_sss_amp_odnoklassniki img{background-color: #F2720C}.heateor_sss_amp_oknotizie img{background-color: #fdff88}.heateor_sss_amp_outlook_com img{background-color: #0072C6}.heateor_sss_amp_papaly img{background-color: #3AC0F6}.heateor_sss_amp_pinboard img{background-color: #1341DE}.heateor_sss_amp_plurk img{background-color: #CF682F}.heateor_sss_amp_pocket img{background-color: #ee4056}.heateor_sss_amp_polyvore img{background-color: #2A2A2A}.heateor_sss_amp_printfriendly img{background-color: #61D1D5}.heateor_sss_amp_protopage_bookmarks img{background-color: #413FFF}.heateor_sss_amp_pusha img{background-color: #0072B8}.heateor_sss_amp_qzone img{background-color: #2B82D9}.heateor_sss_amp_refind img{background-color: #1492ef}.heateor_sss_amp_rediff_mypage img{background-color: #D20000}.heateor_sss_amp_renren img{background-color: #005EAC}.heateor_sss_amp_segnalo img{background-color: #fdff88}.heateor_sss_amp_sina_weibo img{background-color: #ff0}.heateor_sss_amp_sitejot img{background-color: #ffc800}.heateor_sss_amp_skype img{background-color: #00AFF0}.heateor_sss_amp_sms img{background-color: #6ebe45}.heateor_sss_amp_slashdot img{background-color: #004242}.heateor_sss_amp_stumpedia img{background-color: #EDEDED}.heateor_sss_amp_svejo img{background-color: #fa7aa3}.heateor_sss_amp_symbaloo_feeds img{background-color: #6DA8F7}.heateor_sss_amp_telegram img{background-color: #3DA5f1}.heateor_sss_amp_trello img{background-color: #1189CE}.heateor_sss_amp_tuenti img{background-color: #0075C9}.heateor_sss_amp_twiddla img{background-color: #EDEDED}.heateor_sss_amp_typepad_post img{background-color: #2A2A2A}.heateor_sss_amp_viadeo img{background-color: #2A2A2A}.heateor_sss_amp_viber img{background-color: #8B628F}.heateor_sss_amp_wordpress img{background-color: #464646}.heateor_sss_amp_wykop img{background-color: #367DA9}.heateor_sss_amp_yahoo_mail img{background-color: #400090}.heateor_sss_amp_yahoo_messenger img{background-color: #400090}.heateor_sss_amp_youmob img{background-color: #3B599D}.heateor_sss_amp_gentlereader img{background-color: #46aecf}.heateor_sss_amp_threema img{background-color: #2A2A2A}.heateor_sss_amp_bluesky img{background-color:#0085ff}.heateor_sss_amp_threads img{background-color:#000}.heateor_sss_amp_raindrop img{background-color:#0b7ed0}.heateor_sss_amp_micro_blog img{background-color:#ff8800}.heateor_sss_amp amp-img{border-radius:999px;} .amp-logo amp-img{width:190px} .amp-menu input{display:none;}.amp-menu li.menu-item-has-children ul{display:none;}.amp-menu li{position:relative;display:block;}.amp-menu > li a{display:block;} /* Inline styles */ div.acss138d7{clear:both;}div.acssf5b84{--relposth-columns:3;--relposth-columns_m:2;--relposth-columns_t:2;}div.acssae964{aspect-ratio:1/1;background:transparent no-repeat scroll 0% 0%;height:150px;max-width:150px;}div.acss6bdea{color:#333333;font-family:Arial;font-size:12px;height:75px;}div.acsse3e3c{font-weight:bold;}amp-img.acss334b9{max-width:35px;} .icon-widgets:before {content: "\e1bd";}.icon-search:before {content: "\e8b6";}.icon-shopping-cart:after {content: "\e8cc";}
Blueprints — это система визуального скриптинга Unreal Engine 4. Она является быстрым способом создания прототипов игр. Вместо построчного написания кода всё можно делать визуально: перетаскивать ноды (узлы), задавать их свойства в интерфейсе и соединять их «провода».
Кроме быстрого прототипирования, Blueprints также упрощают создание скриптов для непрограммистов.
В этой части туториала мы будем использовать Blueprints для следующих операций:
Примечание: в этой части предполагается, чтоб вы знаете интерфейс Unreal Engine 4. Вы должны понимать основные концепции Blueprint, такие как компоненты и ноды. Если вам нужно освежить знания, то прочитайте первую часть туториала по Unreal Engine 4.
В этой части также используются векторы. Если вы с ними незнакомы, то рекомендую эту статью про векторы на gamedev.net.
Примечание: эта статья является одной из восьми частей туториала, посвящённого Unreal Engine:
Скачайте начальный проект и распакуйте его. Чтобы открыть проект, перейдите в папку проекта и откройте BananaCollector.uproject.
Примечание: если откроется окно, сообщающее, что проект создан в более ранней версии Unreal editor, то всё в порядке (движок часто обновляется). Можно или выбрать опцию создания копии, или опцию преобразования самого проекта.
На рисунке ниже показана сцена. Именно в ней игрок будет перемещаться и собирать предметы.
Для простоты навигации я разбил файлы проекта на папки, как показано на рисунке:
Выделенную красным кнопку можно использовать, чтобы показать или скрыть панель исходников.
В Content Browser перейдите к папке Blueprints. Нажмите на кнопку Add New и выберите Blueprint Class.
Мы хотим, чтобы актор получал вводимую игроком информацию, поэтому нам подходит класс Pawn. Выберите во всплывающем окне Pawn и назовите его BP_Player.
Примечание: класс Character тоже подойдёт. В нём даже по умолчанию есть компонент перемещения. Однако мы будем реализовывать собственную систему движения, поэтому класса Pawn нам достаточно.
Камера — это способ игрока смотреть на мир. Мы создадим камеру, смотрящую на игрока сверху вниз.
В Content Browser дважды нажмите на BP_Player, чтобы открыть его в Blueprint editor.
Для создания камеры перейдите на панель Components. Нажмите на Add Component и выберите Camera.
Чтобы камера смотрела сверху вниз, нужно расположить её над игроком. Выбрав компонент камеры, перейдите во вкладку Viewport.
Активируйте манипулятор перемещения, нажав клавишу W, а затем переместите камеру в (-1100, 0, 2000). Или же можно ввести координаты в поля Location. Она находится в разделе Transform панели Details.
Если вы потеряли камеру из виду, нажмите клавишу F, чтобы сфокусироваться на ней.
Затем активируйте манипулятор поворота, нажав клавишу E. Поверните камеру вниз на -60 градусов по оси Y.
Мы обозначим персонажа игрока красным кубом, поэтому для его отображения нужно будет использовать компонент Static Mesh.
Во-первых, снимите выделение с компонента Camera, нажав левой клавишей мыша на пустом пространстве в панели Components. Если этого не сделать, то следующий добавленный компонент будет дочерним по отношению к камере.
Нажмите на Add Component и выберите Static Mesh.
Чтобы отобразить красный куб, выберите компонент Static Mesh, а затем перейдите во вкладку Details. Нажмите на раскрывающийся список, находящийся справа от Static Mesh и выберите SM_Cube.
Вы должны увидеть следующее (можно нажать F внутри Viewport, чтобы сфокусироваться на кубе, если вы его не видите):
Теперь настало время заспаунить актора Pawn игрока. Нажмите на Compile и вернитесь к основному редактору.
Чтобы игрок мог управлять Pawn, нужно указать две вещи:
Первую задачу можно выполнить, создав новый класс Game Mode.
Класс Game Mode (игровой режим) — это класс, управляющий тем, как игрок входит в игру. Например, в многопользовательской игре Game Mode используется для задания спауна каждого игрока. Что более важно, Game Mode определяет, какой Pawn будет использовать игрок.
Перейдите к Content Browser и зайдите в папку Blueprints. Нажмите на кнопку Add New и выберите Blueprint Class.
Во всплывающем меню выберите Game Mode Base и назовите его GM_Tutorial.
Теперь нужно указать, какой класс Pawn будет использоваться по умолчанию. Дважды нажмите на GM_Tutorial, чтобы открыть его.
Перейдите на панель Details и загляните в раздел Classes. Нажмите на раскрывающийся списокDefault Pawn Class и выберите BP_Player.
Чтобы использовать новый Game Mode, нужно сообщить уровню, какой Game Mode он должен использовать. Это можно указать в World Settings. Нажмите на Compile и закройте Blueprint editor.
Каждый уровень имеет собственные параметры. Получить доступ к этим параметрам можно, выбрав Window\World Settings. Или же можно зайти в Toolbar и выбрать Settings\World Settings.
Рядом со вкладкой Details откроется новая вкладка World Settings. В ней нажмите на раскрывающийся список GameMode Override и выберите GM_Tutorial.
Теперь вы увидите, что классы сменились на те, которые выбраны в GM_Tutorial.
Наконец, нам нужно задать точку спауна игрока. Это реализуется размещением на уровне актора Player Start.
В процессе спауна игрока Game Mode ищет актор Player Start. Если Game Mode находит его, то предпринимает попытку заспаунить игрока там.
Чтобы разместить Player Start, перейдите к панели Modes и найдите Player Start. Нажмите левой клавишей и перетащите Player Start из панели Modes во Viewport. Отпустите левую клавишу мыши, чтобы разместить его.
Можете разместить его где угодно. Когда закончите, перейдите в Toolbar и нажмите Play. Вы будете заспаунены в точке расположения Player Start.
Чтобы выйти из игры, нажмите кнопку Stop в Toolbar или нажмите клавишу Esc. Если вы не видите курсор, нажмите Shift+F1.
Это не похоже на игру, если мы не можем двигаться. Наша следующая задача — настроить параметры ввода.
Назначение клавиши действию называется привязкой клавиши.
В Unreal можно настроить привязки клавиш, чтобы при их нажатии срабатывали события. События — это ноды, выполняющиеся при определённых действиях (в этом случае — при нажатии указанной клавиши). При срабатывании события выполняются все ноды, соединённые с событием.
Такой способ привязки клавиш удобен, потому что он означает, что нам не нужно жёстко задавать клавиши в коде.
Например, можно привязать нажатие левой клавиши мыши и назвать её Shoot. Любой актор, умеющий стрелять, может использовать событие Shoot, чтобы знать, когда игрок нажимает на левую клавишу мыши. Если вы хотите изменить клавишу, то это можно сделать в параметрах ввода.
Если мы будем задавать клавиши жёстко, то нам придётся заходить в каждый актор и менять клавиши отдельно.
Чтобы перейти к параметрам ввода, зайдите в Edit\Project Settings. В разделе Engine выберите слева Input.
В разделе Bindings выполняется настройка ввода.
Unreal предоставляет два способа создания привязок клавиш:
В этом туториале мы будем использовать привязки осей.
Во-первых, мы создадим две группы привязки осей. Группы позволяют привязывать несколько клавиш к одному событию.
Для создания новой группы привязки осей нажмите на значок + справа от Axis Mappings. Создайте две группы и назовите их MoveForward и MoveRight.
MoveForward будет управлять движением вперёд и назад. MoveRight будет управлять движением влево и вправо.
Мы привяжем движение к четырём клавишам: W, A, S и D. Пока у нас есть только два слота для привязки клавиш. Добавим к каждой группе ещё одну привязку осей, нажав на значок + рядом с полем имени группы.
Чтобы привязать клавишу, нажмите на раскрывающийся список с перечислением клавиш. Привяжите клавиши W и S к MoveForward. Привяжите клавиши A и D к MoveRight.
Теперь нужно задать значения в полях Scale.
Перед заданием полей Scale нам нужно больше узнать о том, как работать со значениями осей.
Значение оси — это численное значение, определяемое типом ввода и способом его использования. При нажатии на кнопки и клавиши на выход подаётся 1. Стики имеют выходные значения от -1 до 1, зависящие от направления и наклона стика.
Мы можем использовать значение оси для управления скоростью Pawn. Например, если мы нажмём стик до упора, то значение оси будет 1. Если нажать наполовину, то значение будет 0.5.
Умножая значение оси на переменную скорости, мы можем регулировать с помощью стика скорость движения.
Также значение оси можно использовать для задания направления вдоль оси. Если умножить скорость Pawn на положительное значение оси, то мы получим положительное смещение. При использовании отрицательного значения оси получим отрицательное смещение. Прибавляя это смещение к местонахождению Pawn, мы задаём направление его движения.
Клавиши клавиатуры могут подавать на выход только значения 1 или 0, то можно использовать scale для преобразования их в отрицательные числа. Это можно сделать, взяв значение оси и умножив его на масштаб.
Умножив положительное (значение оси) на отрицательный (масштаб), мы получим отрицательное значение.
Задайте масштаб клавиш S и A, нажав на поле Scale и введя -1.
Теперь начинается интересное: заставим Pawn двигаться! Закройте Project Settings и откройте BP_Player в Blueprints editor, дважды нажав на него.
Сначала нам нужно выбрать события для привязок движения. Нажмите правой клавишей мыши на пустом пространстве в Event Graph, чтобы открыть список нодов. Найдите в этом меню MoveForward. Добавьте нод MoveForward из списка Axis Events. Учтите, что вам нужен красный нод в Axis Events, а не зелёный нод в Axis Values.
Повторите процесс для MoveRight.
Теперь мы настроим ноды для MoveForward.
Для перемещения необходимо указать, с какой скоростью будет двигаться Pawn. Один из простых способов указания скорости — хранение её в переменной.
Чтобы создать переменную, зайдите во вкладку My Blueprint и нажмите на значок + в правой части раздела Variables.
Выбрав новую переменную, перейдите во вкладку Details. Измените имя переменной на MaxSpeed. После этого замените тип переменной на Float. Для этого нужно нажать на раскрывающийся список рядом с Variable Type и выбрать Float.
Теперь необходимо задать значение по умолчанию. Но чтобы его задать, нужно будет нажать Compile в Toolbar.
Выбрав переменную, перейдите ко вкладке Details. Зайдите в раздел Default Value и измените значение MaxSpeed по умолчанию на 10.
Затем перетащите переменную MaxSpeed из вкладки My Blueprint на Event Graph. Выберите из меню пункт Get.
Теперь нужно умножить MaxSpeed на значение оси, чтобы получить конечную скорость и направление. Добавим нод float * float и присоединим к нему Axis Value и MaxSpeed.
Чтобы двигаться вперёд, нам нужно знать, куда смотрит Pawn. К счастью, в Unreal есть для этого нод. Добавьте нод Get Actor Forward Vector.
Затем добавьте нод Add Movement Input. Этот нод получает направление и значение, преобразуя их в хранимое смещение. Соедините ноды следующим образом:
Белая линия обозначает цепочку выполнения. Другими словами, когда игрок перемещает ось ввода, то генерируется событие, выполняющее нод InputAxis MoveForward. Белая линия показывает, что после этого выполняется нод Add Movement Input.
Нод Add Movement Input получает на входе следующие данные:
Повторим процесс для MoveRight, но заменим Get Actor Forward Vector на Get Actor Right Vector. Попробуйте сделать всё сами, не сверяясь с вышеприведёнными инструкциями!
Чтобы действительно двигать Pawn, нам нужно получить смещение, вычисленное Add Movement Input, и прибавить его к местоположению Pawn.
В сущности, наша стратегия будет заключаться в перемещении игрока на небольшую величину в каждом кадре игры, поэтому нам нужно добавить перемещение к событию Event Tick, которое генерируется каждый кадр.
Перейдите к ноду Event Tick в Event Graph. Он должен быть неактивным и находиться слева, но если его нет, то создайте нод самостоятельно.
Чтобы действительно двигать Pawn, нам нужно получить смещение, вычисленное Add Movement Input, и прибавить его к местоположению Pawn.
В сущности, наша стратегия будет заключаться в перемещении игрока на небольшую величину в каждом кадре игры, поэтому нам нужно добавить перемещение к событию Event Tick, которое генерируется каждый кадр.
Перейдите к ноду Event Tick в Event Graph. Он должен быть неактивным и находиться слева, но если его нет, то создайте нод самостоятельно.
Это означает, что в каждом кадре игры мы будем сохранять весь ввод перемещения и прибавлять его к текущему местоположению актора.
Нажмите Compile, перейдите к основному редактору и нажмите на Play. Теперь вы можете двигаться в сцене!
Однако у нас есть небольшая проблема. Мощные компьютеры могут рендерить кадры с большей частотой. Event Tick вызывается каждый кадр, поэтому ноды перемещения будут выполняться чаще. Это значит, что Pawn будет двигаться на мощных компьютерах быстрее, и наоборот.
Чтобы решить эту проблему, наше движение должно быть независимым от частоты кадров.
Примечание: я настроил привязки клавиш, чтобы показать влияние зависимости от частоты кадров. Нажмите 0, чтобы ограничить частоту 60 кадрами в секунду, и нажмите 1, чтобы снять ограничение. Попробуйте перемещаться при обоих частотах кадров и вы заметите разницу в скорости.
Независимость от частоты кадров означает, что мы постоянно будем получать одинаковые результаты, вне зависимости от частоты кадров. К счастью, достичь такой независимости в Unreal очень просто.
Выйдите из игры, а затем откройте BP_Player. Затем перейдите к узлу Event Tick и посмотрите на Delta Seconds.
Delta Seconds — это величина времени, прошедшего после предыдущего Event Tick. Умножив смещение на Delta Seconds, мы сделаем перемещение независимым от частоты кадров.
Например, наш Pawn имеет максимальную скорость 100. Если после предыдущего Event Tick прошла одна секунда, то Pawn переместится на полные 100 единиц. Если прошли полсекунды, то он переместится на 50 единиц.
Если движение зависимо от частоты кадров, то Pawn будет перемещаться на 100 единиц в каждом кадре, вне зависимости от времени между кадрами.
Чтобы умножить смещение на Delta Seconds, добавьте нод vector * float. После этого соедините ноды следующим образом:
Время между кадрами (Delta Seconds) очень мало, поэтому Pawn будет двигаться намного медленнее. Это можно исправить, заменив значение MaxSpeed по умолчанию на 600.
Поздравляю вам удалось добиться независимости от частоты кадров!
Можно заметить, что куб проходить сквозь все объекты. Чтобы исправить это, нам нужно познакомиться с коллизиями.
Надевайте шлем, потому что сейчас нам придётся столкнуться с теорией!
Когда мы вспоминаем о столкновениях, то представляем автомобильные аварии. К счастью, коллизии в Unreal намного безопаснее.
Чтобы иметь возможность сталкиваться с объектами, актору нужно обозначение его пространства столкновений (обычно называемого коллизией). Можно использовать одно из следующих пространств:
Ниже представлен пример персонажа и его коллизии.
Коллизия происходит, когда коллизия актора касается коллизии другого актора.
Теперь настало время включить коллизии.
Вы, наверно, недоумеваете, почему куб не сталкивается с объектами, хотя у него есть меш коллизии. При перемещении актора Unreal учитывает для коллизий только корневой компонент. Поскольку корневой компонент Pawn не имеет коллизии, он проходит сквозь все объекты.
Примечание: актор, не имеющий коллизии в корневом компоненте, всё равно может блокировать других акторов. Но если перемещать актора, то он не будет ни с чем сталкиваться.
Итак, чтобы использовать меш коллизии, StaticMesh должен быть корневым. Для этого перейдите в панель Components. Затем зажмите левую клавишу мыши и перетащитеStaticMesh на DefaultSceneRoot. Отпустите левую клавишу мыши, чтобы сделать StaticMesh новым корневым компонентом.
Чтобы коллизии начали работать, нужно выполнить ещё одно действие. Переключитесь на Event Graph и перейдите к узлу AddActorLocalOffset. Найдите вход Sweep и измените значение на true, нажав левой клавишей мыши на флажок.
AddActorLocalOffset занимается тем, что телепортирует актора в новое место. Sweep гарантирует, что актор будет сталкиваться со всем, что находится между старым и новым местоположением.
Перейдите в основной редактор и нажмите на Play. Теперь куб будет реагировать на коллизии с уровнем!
Последнее, что мы создадим — это предмет, исчезающий при контакте с персонажем игрока.
В общем случае предметом является любой собираемый игроком объект. Мы используем в качестве предмета BP_Banana.
Чтобы распознать контакт куба и предмета, нам нужен нод события, срабатывающего при коллизии. Для генерирования таких событий можно использовать реакции на коллизи.
Реакция на коллизию также определяет, как актор реагирует на коллизию с другим актором. Существует три типа реакций на коллизии: Ignore, Overlap и Block. Вот как они взаимодействуют друг с другом:
Хотя здесь можно использовать и Overlap, и Block, в этом туториале мы будем использовать только Overlap.
Закройте игру и откройте BP_Banana. Выберите компонент StaticMesh, а затем перейдите в панель Details. Реакции на коллизии задаются в разделе Collision.
Как вы видите, большинство параметров неактивно. Чтобы сделать их изменяемыми, нажмите на раскрывающийся список рядом с Collision Presets. Выберите в списке Custom.
Теперь нам нужно указать реакцию на коллизию между предметом и кубом.
Компоненты имеют атрибут под названием object type (тип объекта). Тип объекта — это просто удобный способ группировки похожих акторов. Подробнее о типах объектов можно прочитать здесь.
Куб имеет тип WorldDynamic, поэтому нам нужно изменить реакцию на коллизию этого типа. В разделе Collision Responses измените реакцию на коллизию WorldDynamic на Overlap. Это можно сделать, нажав на средний флажок справа от WorldDynamic.
Для обработки коллизий нужно использовать событие наложения. Перейдите в панель Components и нажмите правой клавишей мыши на StaticMesh. В контекстном меню выберите Add Event\Add OnComponentBeginOverlap.
Так мы добавим в Event Graph нод OnComponentBeginOverlap (StaticMesh).
Наконец, создадим нод DestroyActor и соедините его с нодом OnComponentBeginOverlap (StaticMesh). Как можно догадаться по названию, он удаляет целевой актор из игры. Однако поскольку целевого актора нет, он уничтожит актор, вызвавший его.
Закройте Blueprint editor и перейдите в папку Blueprints.
Начните располагать бананы на уровне зажав левую клавишу мыши и перетаскиваяBP_Banana во Viewport.
Нажмите Play и начните собирать бананы!
Готовый проект можно скачать отсюда.
Вы сделали ещё один шаг к тому, чтобы стать специалистом по Unreal Engine.
Если вы хотите продолжить обучение, то прочитайте следующий пост в серии, где мы подробнее рассмотрим материалы Unreal Engine.
В Unity используется производительный язык программирования C#. Благодаря C# и Mono – кроссплатформенной реализации .NET,…