آموزش ویدئویی بازی‌سازی با Unity - جلسه نهم: تغییر مراحل و انیمیشن
1398/02/30 10:54 , میلاد صاحب نظر

آموزش ویدئویی بازی‌سازی با Unity - جلسه نهم: تغییر مراحل و انیمیشن

در این قسمت به یکی از مهم‌ترین بخش‌های هر بازی که تا الان نبودنش خیلی احساس می‌شد می‌پردازیم. بردن در بازی و به کار بردن انیمیشن برای نشان دادن آن و رفتن به مرحله بعدی از جمله مباحث این قسمت هستند. با ما همراه باشید!

مقدمه: آشنایی با موتور بازی‌سازی Unity قسمت سوم: حرکات قسمت ششم: GAMEPLAY قسمت نهم: تغییر مراحل و انیمیشن
قسمت اول: اصول اولیه Unity قسمت چهارم: دوربین دنبال‌گر قسمت هفتم: امتیاز‌دهی (SCORE) و UI قسمت دهم: پایان بازی
قسمت دوم: برنامه‌نویسی در Unity قسمت پنجم: برخورد قسمت هشتم: Game Over  

 برای اینکه بتوانیم به سیستم بفهمانیم که مرحله به اتمام رسیده است، باید یک Trigger در انتهای مرحله ایجاد کنیم. trigger یک رویه یا procedure ذخیره شده است که اگر یک تغییر خاصی در برنامه ایجاد شود، فعالیت خاصی را انجام می‌دهد.

در این بازی ما از trigger برای شروع فرآیند نمایش صفحه برنده شدن یا تبریک به کاربر و سپس رفتن به مرحله بعدی، استفاده می‌کنیم.

برای ایجاد trigger در یونیتی باید به قسمت hierarchy بروید، کلیک راست کنید، به بخش 3d objects بروید و یک cube انتخاب کنید. 

همانطور که احتمالا حدس زدید، ما قصد داریم با ایجاد یک شیء در صفحه و برخورد بازیکن با آن شیء، فرآیند trigger را شبیه سازی کنیم. پس ابعاد شیء ایجاد شده را با زمین بازی منطبق کنید تا مطمئن شوید که شیء بازیکن حتما با آن برخورد کند.

حالا نامی برای آن انتخاب کنید (مثلا End) و شیء را به انتهای مرحله‌ای که طراحی کردید ببرید. نکته مهم این است که کاربر نباید بتواند این شیء trigger را ببیند، پس در قسمت componentها، Mesh Renderer را غیر فعال کنید.

همچنین باید Box Collider هم فعال باشد تا برنامه متوجه برخورد بازیکن با شیء بشود، اما حتما تیک گزینه is trigger را بزنید تا همانند یک مانع معمولی با شیء برخورد نشود.

بسیار خب، حالا باید یک اسکریپت جدید ایجاد کنید تا به واسطه آن به Game Manager خبر دهید که به انتهای مرحله رسیده‌اید. پس یک اسکریپت به نام EndTrigger ایجاد کرده و روی آن دبل کلیک کنید تا وارد ویژوال استودیو شوید.

مثل همیشه تگ‌های using و دو متد Start و update را حذف کنید. ممکن است بر اساس مباحثی که در جلسات قبل آموختید بخواهید این برخورد را نیز با کد OnCollitionEnter تشخیص دهید.

اما نکته جدیدی که باید بیاموزید این است که اگر شیئی در قسمت box collider به عنوان is trigger مشخص شده باشد، دستور OnCollitionEnter دیگر برای آن کار نمی‌کند.

پس در عوض، برای تشخیص برخورد با شیء Trigger از دستور OnTriggerEnter استفاده می‌کنیم. کاری که باید پس از تشخیص برخورد انجام دهیم، این است که به Game Manager بگوییم یک UI در صفحه برای تبریک گفتن به کاربر نشان بده.

برای این منظور به یک رفرنس به سمت Game Manager نیاز داریم. البته می‌توانیم همانند قسمت قبلی از دستور FindObjectOfType هم استفاده کنیم، اما چون این شیء قرار نیست نابود و دوباره ایجاد شود، پس به صرفه‌تر است که از روش ایجاد رفرنس استفاده کنیم.

برای این منظور به یونیتی برگردید و وارد کدهای اسکریپت Game Manager شوید. در این اسکریپت در جلسه قبل کدی برای پایان دادن به بازی در صورت برخورد با مانع و Restart کردن بازی داریم. اما حالا به یک تابع نیاز داریم تا در صورت برنده شدن اجرا شود.

پس در این اسکریپت یک تابع به شکل زیر ایجاد کنید:

public void CompleteLevel()
{
Debug.Log("Level WON!");
}

در این کد فعلا قصد داریم ببینیم آیا این تابع در زمان درست (یعنی وقتی بازیکن در مرحله موفق می‌شود) فراخوانی می‌شود یا خیر. پس فقط یک پیام در کنسول نمایش می‌دهیم. بازی را Save کنید و به یونیتی برگردید. 

حالا دوباره به اسکریپت EndTriiger بروید و کدهای زیر را در آن بنویسید:

public GameManager gameManager;
void OnTriggerEnter()
{
gameManager.CompleteLevel();
{

در اسکریپت EndTrigger ابتدا یک متغیر به نام gameManager ایجاد کردیم. سپس در تابع OnTriggerEnter با استفاده از این متغیر، تابعی که در اسکریپت GameManager ساختیم (یعنی تابع CompleteLevel) را فراخوانی کردیم.

 همچنین باید این رفرنس را تکمیل کنید. پس کد را save کنیده، به یونیتی برگردید، شیء END را انتخاب کنید و Game Manager را به درون محل خالی drag کنید. 

حالا اگر بازی را play کنید و تا انتهای مرحله بروید، مشاهده خواهید کرد که در درون کنسول پیام !LEVEL WON چاپ می‌شود. 

نکته: اگر هر شیء دیگری جز بازیکن هم به trigger برخورد کند، باز هم این پیان چاپ می‌شود (مثلا اگر به مانعی برخورد کنید و آن مانع پرتاب شود و به trigger برسد).

برای جلوگیری از این وضعیت و اینکه trigger فقط زمانی فعال شود که player با آن برخورد می‌کند، می‌توانید از همان روشی که برای Player Collition در قسمت collition به کار بردیم، استفاده کنید تا برنامه بررسی کند که چه شیء به trigger برخورد می‌کند و فقط اگر شیئی که برخورد می‌کند Player باشد، trigger را فعال کند.

حالا مطمئن شدیم که تابع ما در زمان مناسب و صحیحی فراخوانی می‌شود. پس حالا باید به جای چاپ یک پیام، به Game Manager بگوییم که UI تبریک و اتمام مرحله را به کاربر نمایش دهد.

برای این منظور، به قسمت Canvas بروید، کلیک راست کنید، به قسمت UI بروید و Panel را انتخاب کنید. حالا دید بازی را به حالت دو بعدی تغییر دهید و زوم را بالا ببرید تا کامل پنل را مشاهده کنید. 

قصد ما این است که این پنل پشت‌زمینه متن تبریک یا تکمیل مرحله باشد، پس ترجیحا فعلا با مثال بازی دوره پیش بروید و همانند ویدئو آن را به رنگ کاملا سفید تغییر دهید و نام آن را LevelComplete بگذارید.

حالا روی همین شیء در قسمت Canvas کلیک راست کنید، به UI بروید و Text را انتخاب کنید. حالا زمینه Text را روی پنل مشخص کنید، آن را وسط چین کنید و یک فونت مناسب برای آن انتخاب کنید.

متن این Text را بنویسید LEVEL و همچنین نام شیء این متن را نیز Level بگذارید. حالا با زدن کلید‌های Ctrl+D شیء را کپی کنید و به جای متن آن بنویسید COMPLETE، نام شیء را نیز Complete بگذارید.

بسیار خب این همان UI است که پس از اتمام مرحله قرار است نمایش داده شود. حالا روی شیء Level Complete کلیک کنید و با برداشتن تیک آن در قسمت بالا سمت راست صفحه آن را غیر فعال کنید تا در ابتدا و در طول بازی نمایش داده نشود.

حالا وارد اسکریپت Game Manager شوید. باید یک رفرنس به سمت UI ایجاد کنید تا وقتی که مرحله را تکمیل کردید آن را فعال کند. پس یک متغیر همانند کد زیر ایجاد کنید:

public GameObject CompleteLevelUI;

حالا در تابع CompleteLevel کد زیر را بنویسید: 

public void CompleteLevel()
{
CompleteLevelUI.SetActive(True);
}

با این کد، به برنامه دستور دادیم که وقتی مرحله تمام شد، یعنی وقتی player به trigger برخورد کرد، آنگاه UI مورد نظر ما را فعال کند. کد را Save کنید، به یونیتی بروید و UI که ایجاد کردید را به درون محل خالی که در سمت راست ایجاد شده است drag کنید تا رفرنس شما ایجاد شود.

حالا اگر بازی را Play کنید و برنده شوید مشاهده خواهید کرد که UI نمایش داده می‌شود. اما هنوز هیچ انیمیشنی ندارد و کمی کسل کننده است. پس برویم به سراغ ایجاد انیمیشن.

ایجاد انیمیشن در بازی

برای ایجاد انیمیشن برای UI که ایجاد کردید، روی آن کلیک کنید (یعنی روی Level Complete)، به سربرگ window بروید و Animation را انتخاب کنید تا پنل انیمیشن ظاهر شود.

نکته: دو گزینه برای انیمیشن وجود دارند: ۱- Animation و ۲- Animator. انیمیشن برای اعمال انواع مشخصات و رفتارهای انیمیشنی روی اشیاء است. در حالی که Animator مسئول اجرا و ترتیب دادن انیمیشن‌ها در کل بازی است. ما فقط یک انیمیشن داریم پس کاری با Animator نداریم.

بسیار خب، در پنجره انیمیشن روی Create کلیک کنید، یک فولدر مجزا برای انیمیشن‌ها ایجاد کنید و نام انیمیشن خود را Level Complete بگذارید و open را بزنید. حالا اگر به پنل پروژه خود بروید، مشاهده خواهید کرد که یک فولدر با نام انیمیشنی که انتخاب کردید وجود دارد.

اگر آن را باز کنید درون آن دو ابزار وجود دارند. اولین ابزار خود انیمیشن است. روی آن کلیک کنید و در پنجره ابزاری که در سمت راست صفحه باز می‌شود، تیک گزینه Looping را بردارید، چون می‌خواهید این انیمیشن فقط یک بار اجرا شود.

دومین ابزار Animation Controller یا همان Animator است. اگر چندین انیمیشن در صفحه داشته باشید، می‌توانید در این قسمت آن را نظم و ترتیب دهید.

بسیار خب، وارد پنجره انیمیشن و صفحه بازی بشوید. مشاهده خواهید کرد که کلید‌های play بازی به رنگ قرمز درآمده‌اند. دلیل این است که در حالت ضبط قرار دارید. در این حالت اگر هر تغییری روی این شیء انجام دهید، به عنوان یک keyframeدر پنل انیمیشن ضبط می‌شود.

برای مثال اگر روی ثانیه ۱ کلیک کنید و رنگ پنل UI را به سمت تیره شدن ببرید، مشاهده خواهید کرد که یک علامت آبی (keyframe) در ثانیه صفر و یکی در ثانیه ۱ ایجاد شده است و اگر پنل انیمیشن را play کنید خواهید دید که پنل از رنگ سفید به بی‌رنگ می‌رود.

مسلما این اتفاق باید برعکس بیفتد، یعنی UI باید ظاهر شود پس جای این دو keyframe را با هم عوض کنید. همین تغییرات را برای اشیاء متن Level و Complete نیز انجام دهید. (برای درک بهتر به ویدئو مراجعه کنید)

وقتی از انیمیشنی که ایجاد کردید رضایت یافتید، روی کلید قرمز رنگ در سمت چپ پنل انیمیشن کلیک کنید تا از حالت ضبط خارج شوید. به این شکل انیمیشن بازی را ایجاد کردید و اگر بازی را اجرا کنید و به انتهای مرحله برسید آن را مشاهده خواهید کرد.

نکته آخری که در این قسمت بیان می‌شود این است که می‌توانید از طریق اسکریپت، در یک زمان خاص از انیمیشن، کار خاصی انجام دهید. مثلا می‌توانید به برنامه بگویید چند ثانیه پس از نمایش UI موفقیت و تبریک، به مرحله بعدی برو.

بنابراین، در پنل انیمیشن روی ثانیه ۲ کلیک کنید و همانطور که در ویدئو نمایش داده شده است، یک event یا رویداد اضافه کنید. این رویداد انیمیشن به اما اجازه می‌دهد یک تابع انتخاب کنیم، خود یونیتی تعداد زیادی تابع برای انتخاب به شما ارائه می‌دهد.

اما ما به اسکریپتی نیاز داریم که روی شیء انیمیشن شده ما (Complete level) بنشیند و مرحله بعدی را load یا بارگذاری کند. پس یک اسکریپت به نام LevelComplete ایجاد کنید و وارد کدهای آن شوید.

کدهای اضافی همیشگی را حذف کنید و تگ زیر را اضافه کنید:

using UnityEngine.SceneManagement;

حالا کد زیر را در این اسکریپت بنویسید: 

public void LoadNextLevel()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildindex + 1);
}

 در این کد تابعی به نام LoadNextLevel ساخته‌ایم که می‌توانید در لیست تابع‌های رویدادی که ایجاد کردید آن را بیابید. این تابع در ثانیه ۲ پس از اتمام مرحله توسط بازیکن، مرحله بعدی بازی را بارگذاری می‌کند.

می‌توانستیم پس از کد LoadScene در پرانتزها راحت نام مرحله بعدی را بنویسیم، اما اگر چندین مرحله داشته باشید، این روش اصلا به صرفه نیست. 

پس در عوض از build indexها که در جلسه پیش معرفی کردیم استفاده شد. به این شکل که کد با استفاده از دستور SceneManager.GetActiveScene صحنه‌ای که در حال حاضر در آن هستیم را می‌یابد.

سپس با استفاده از دستور buildindex، شماره buildindex آن صفحه را به دست می‌آورد و آن را با ۱ جمع می‌کند تا build index مرحله بعدی بازی به دست آید و آن مرحله بارگذاری شود. کار دیگری با این اسکریپت نداریم پس آن را Save کنید و به یونیتی بازگردید.

اگر الان بازی را play کنید، پس از اتمام مرحله با ارور مواجه خواهید شد چون در صف مراحل بازی در build settings هیچ مرحله دیگری وجود ندارد که بارگذاری شود.

نکته‌ای که می‌آموزید این است که اگر اینچنین کد نویسی کردید، همیشه باید یک مرحله دیگر وجود داشته باشد، یا اینکه یک صفحه تبریک به بازیکن برای اتمام تمام مراحل نشان دهید و بازی را تمام کنید که این مورد در قسمت بعدی توضیح داده خواهد شد.

در حال حاضر فقط یک مرحله دیگر ایجاد می‌کنیم. پس کلید‌های Ctrl+s را بزنید تا صحنه فعلی شما save شود. در پنل پروژه روی Level 1 کلیک کنید و کلیدهای Ctrl+D را بزنید تا کپی شود. با پاک کردن موانع و جا‌به‌جایی بعضی از آن‌ها کمی در مرحله جدید تفاوت ایجاد کنید.

سپس با رفتن به سربرگ file و بعد انتخاب build settings پنجره buile settings را باز کنید و Level 2 را از درون پنل پروژه به درون صف در زیر Level 1 بکشید تا به صف اضافه شود و یک build index به دست آورد.

حالا اگر بازی را play کنید و به پایان مرحله اول برسید، پس از نمایش داده شدن UI مرحله بعدی بارگذاری می‌شود و اگر به پایان مرحله دوم برسید، پس از نمایش دادن UI سیستم ارور می‌دهد چون مرحله دیگری برای بارگذاری نیست. اما نگران نباشید در قسمت آخر این مشکل را رفع می‌کنیم.

بسیار خب این قسمت هم تمام شد و یاد گرفتید تا حد مقدماتی با انیمیشن یونیتی کار کنید و مراحل بعدی خود را بارگذاری کنید. قسمت بعدی آخرین قسمت این دوره مقدماتی خواهد بود و اولین بازی خود را به صورت کامل خروجی خواهید گرفت و تکمیل خواهید کرد.

با  MUG همراه باشید!

منبع: Brackeys

 مطالب مرتبط

 مقدمه ای بر زبان برنامه نویسی #C و پلتفرم NET Framework.
 آموزش گام به گام #C
 طبقه بندی زبان های برنامه نویسی
۷ زبان توسعه بازی Unity برای آموختن: کدام بهترین است؟
۸ بازی ساخته شده با unity توسط تیم‌های کوچک یا تک‌نفره
برنامه نویسی شیءگرا چیست؟

از آخرین دوره های آموزشی و تخفیف ها مطلع شوید

با تکمیل فرم زیر ، از اخبار و اطلاعات به روز برنامه نویسی و تکنولوژی عقب نمانید

آخرین مطالب

آموزش جامع SQL Server (جلسه ۱۲)
آموزش جامع SQL Server (جلسه ۱۲)

دستور UPDATE در SQL Server برای تغییر داده‌های موجود در یک جدول، از دستور UPDATE به شکل زیر استفاده ...

آموزش جامع SQL Server (جلسه ۱۵)
آموزش جامع SQL Server (جلسه ۱۵)

دستور DROP TABLE در SQL Server گاهی، لازم است یک جدول که دیگر استفاده‌ای ندارد را حذف کنید. برای ...

آموزش جامع SQL Server (جلسه ۳۵: Window Functionها – بخش ۲)
آموزش جامع SQL Server (جلسه ۳۵: Window Functionها – بخش ۲)

بخش اول از آخرین مبحث دوره جامع آموزش SQL Server در جلسه قبلی بررسی شد. این مبحث که ...

آخرین دیدگاه ها

دیدگاه خود را درباره این پست بنویسید

فرم ارسال نظرات