انیمیشن در یونیتی (دوبعدی)
انیمیشن قابلیتی است که توسط آن ویژگیهای شی مانند شکل، رنگ، مکان و… در گذر زمان تغییر میکنند. وجود انیمیشن در بازیهای ویدیویی جزئی تقریباً جداییناپذیر در ایجاد جلوه و ظاهر است.
مفهوم انیمیشن در یونیتی با تغییر اتوماتیک پراپرتیهای کامپوننتهای یک گیمآبجکت بر روی آن گیمآبجکت پیادهسازی میشود.
به عنوان مثال برای ایجاد انیمیشن «بالا و پایین پریدن» کافی است که ابتدا مقدار Y پراپرتی Position کامپوننت Transform کمی افزایش یافته و سپس به مقدار قبلی خود باز گردد.
همچنین برای ایجاد انیمیشنهایی که از مجموعه تصاویر ثابت پشت سر هم ساخته میشوند کافی است که در هر فریم پراپرتی Sprite کامپوننت Sprite Renderer گیمآبجکت با یکی از تصاویر ثابت جایگزین شود. این تصاویر که در هر فریم تغییر کوچکی نسبت به فریم قبلی دارند توهم انیمیشن را به بیننده القا میکنند.
فریمهای انیمیشن راه رفتن کاراکتر اصلی بازی Braid
نکته
به texture atlasهایی که حاوی spriteهای یک انیمیشن هستند اصطلاحاً sprite sheet گفته میشود.
برای ایجاد انیمیشن در یونیتی از assetهایی به نام Animation Clip (با فرمت anim) استفاده میشود. این assetها اطلاعات مربوط به تغییر پراپرتیهای موردنظر نسبت به زمان را در خود ذخیره میکنند. هر گیمآبجکت میتواند تعداد نامحدودی از assetهای انیمیشن را بر روی خود پیادهسازی کند. به همین منظور یک asset انیمیشن مستقیماً بر روی گیمآبجکت اعمال نمیشود؛ بلکه ابتدا تمام asset انیمیشنهای موردنظر برای گیمآبجکت (مثل راه رفتن، دویدن، بالا رفتن و…) به صورت مستقل ایجاد شده و سپس در یک asset با فرمت controller قرار میگیرند. این asset در حکم مخزن انیمیشنها بوده که توسط کامپوننت Animator نسبت به اعمال مجموعهی انیمیشنها بر روی گیمآبجکت اقدام میکند.
کامپوننت Animator وظیفهی اعمال انیمیشن بر روی گیمآبجکت را بر عهده دارد.
بعد از قرارگیری تمام انیمیشنها در مخزن controller، با استفاده از ابزاری به نام Animator اقدام به مدیریت آنها میکنیم. با استفاده از این ابزار میتوان تعیین کرد که در هر لحظه کدام انیمیشن موجود در مخزن controller متصل به کامپوننت Animator بر روی گیمآبجکت اعمال شود. برای مثال اگر قصد داشته باشیم که پلیر هنگام حرکت با سرعت کمتر از 3 واحد در ثانیه انیمیشن «راه رفتن» و در سرعتهای بالاتر انیمیشن «دویدن» را بروز دهد باید از این ابزار استفاده کنیم. assetهای controller دادههای این ابزار را نیز ذخیره میکنند.
هنگام اجرای صحنه انیمیشنها مستقیماً بر روی گیمآبجکت اعمال نمیشوند؛ بلکه به controller موجود در پراپرتی Controller کامپوننت Animator آنها رجوع شده و سپس انیمیشن مناسب آن لحظه توسط controller انتخاب شده و بر روی گیمآبجکت اعمال میشود.
نکته
کامپوننت Animation در یونیتی امکان اعمال انیمیشن بر روی گیمآبجکت بدون پیچیدگیهای کار با ابزار Animator را فراهم میکند. البته این کامپوننت به دلیل امکانات فراوان Animator منسوخ شده است.
پس به منظور ایجاد انیمیشن برای یک گیمآبجکت ابتدا به تعداد موردنیاز asset انیمیشن ساخته و آنها را به گیمآبجکت نسبت میدهیم. سپس اقدام به تنظیم آنها نموده و در نهایت از طریق ابزار Animator و controller آنها را مدیریت میکنیم.
مرحلهی اول: ایجاد assetهای انیمیشن و نسبت دادن آنها به گیمآبجکت
به منظور ایجاد asset انیمیشن از منوی Create پنجرهی Project، گزینهی Animation را انتخاب کرده و نام دلخواه خود را برای آن وارد میکنیم. این assetها به طور قراردادی باید در فولدری به نام Animations قرار بگیرند.
از آنجایی که امکان تنظیم و ویرایش یک asset انیمیشن به صورت مستقل و بدون متصل بودن آن به یک گیمآبجکت امکانپذیر نیست پس از ایجاد یک asset انیمیشن با drag کردن آن بر روی نام گیمآبجکت هدف در Hierarchy آن انیمیشن را به گیمآبجکت نسبت میدهیم.
بعد از انجام این کار به صورت خودکار یک asset جدید با فرمت controller و همنام گیمآبجکت در مسیر asset انیمیشن ایجاد میشود. همچنین کامپوننتی به نام Animator به گیمآبجکت افزوده شده که controller ایجاد شده به پراپرتی Controller آن نسبت داده میشود. این مخزن به منظور ذخیرهی انیمیشنهای گیمآبجکت ایجاد شده است.
بعد از این اتفاق با drag کردن assetهای انیمیشن جدید دیگر controller جدیدی برای گیمآبجکت ایجاد نشده و assetها در مخزن controller قبلی قرار میگیرند.
مرحلهی دوم: تنظیم و ویرایش assetهای انیمیشن
بعد از ایجاد assetهای انیمیشن و نسبت دادن آنها به گیمآبجکت نوبت به تنظیم و ویرایش آنها میرسد. برای این کار از پنجرهی Animation (در منوی Window > Animation > Animation) استفاده میشود.
به منظور تنظیم و ویرایش assetهای انیمیشن یک گیمآبجکت توسط پنجرهی Animation، ابتدا گیمآبجکت را از پنجرهی Hierarchy انتخاب میکنیم. بعد از انتخاب شدن یک گیمآبجکت، assetهای انیمیشن موجود در controller آن گیمآبجکت در منوی موجود در کنترل بار پنجرهی Animation لیست میشوند:
از طریق این منو asset انیمیشن موردنظر خود را انتخاب کرده و یا در صورت لزوم با استفاده از گزینهی Create New Clip اقدام به ایجاد یک asset انیمیشن جدید میکنیم.
نکته
در صورتی که یک asset انیمیشن به این صورت ساخته شود به طور اتوماتیک به مخزن controller گیمآبجکت مربوطه اضافه میشود.
بعد از انتخاب asset انیمیشن در پنجرهی Animation، با استفاده از فیلد Samples موجود در این پنجره، سرعت انیمیشن بر حسب فریم بر ثانیه را تعیین میکنیم (این عدد به طور پیشفرض 60 میباشد). هر ثانیه به تعداد عدد وارد شده به بخشهای کوچکتری تقسیم میشود که هرکدام از این بخشها sample (فریم) نامیده شده و امکان ذخیرهی مقادیر پراپرتیها را دارا میباشد. برای مثال در یک انیمیشن 60 فریم بر ثانیه امکان 60 بار مقداردهی یک پراپرتی وجود خواهد داشت.
در اصطلاح انیمیشنسازی به فریمهایی که در آنها مقداردهی صورت میگیرد keyframe گفته میشود. به طور پیشفرض در صورتی که بین دو keyframe چندین فریم خالی وجود داشته باشد، مقدار اولیه در keyframe اول در هر فریم به مقدار ثانویه در keyframe دوم نزدیکتر میشود تا در نهایت در keyframe دوم به آن مقدار برسد. به این وسیله یک انیمیشن ایجاد میشود. بنابراین هر چه مقدار Samples بیشتر باشد انیمیشن نهایی روانتر خواهد بود. البته چشم انسان امکان تشخیص سرعت بیشتر از 30 فریم بر ثانیه را ندارد.
بعد از تعیین فریم ریت، با کلیک بر روی دکمهی Add Property نسبت به اضافه کردن پراپرتیهایی که قصد تغییر آنها در انیمیشن داریم اقدام میکنیم.
در این مرحله بر روی دکمهی Record واقع در نوار کنترل پنجره کلیک کرده و خط زمان (خط عمودی سفید رنگ که زمان را مشخص میکند) را به وسیلهی drag کردن آن از نوار شمارهگذاری شده در بالایش بر روی فریم موردنظر میبریم. سپس پراپرتیهای دلخواه را برای آن فریم مقداردهی میکنیم.
در این هنگام پراپرتیهای تغییر داده شده در ادیتور با هایلایت قرمز متمایز میشوند. همچنین هر keyframe در پنجرهی Animation با یک لوزی نمایش داده میشود.
افزودن event به asset انیمیشن
در صورتی که قصد داشته باشیم در یک فریم خاص از انیمیشن، قطعه کدی اجرا شود از این قابلیت استفاده میکنیم. به این منظور ابتدا کد خود را در قالب یک متد در یکی از اسکریپتهای متصل به گیمآبجکت مینویسیم. سپس خط زمان را به فریم موردنظر برده و بر روی دکمهی Add Event پنجرهی Animation کلیک میکنیم و نام متد موردنظر را از پنجرهی Inspector انتخاب مینماییم.
مرحلهی سوم: مدیریت انیمیشنهای گیمآبجکت با Animator
بعد از تکمیل شدن assetهای انیمیشن یک گیمآبجکت به مدیریت controller آن گیمآبجکت از طریق ابزار Animator میپردازیم. این ابزار که از طریق پنجرهی Animator (از منوی Window > Animation > Animator) قابل دسترسی است پس از انتخاب گیمآبجکت موردنظر ماشین حالت (state machine) انیمیشنهای آن را نمایش میدهد. در این ماشین به ازای هر asset انیمیشن موجود در controller یک حالت وجود دارد:
یک ماشین حالت که در آن سه state انیمیشنهای TestAnimation2، TestAnimation1 و TestAnimation3 قرار دارند
در ماشین حالت انیمیشنها در هر لحظه تنها یک state در حالت فعال قرار داشته و انیمیشن state فعال بر روی گیمآبجکت اعمال میشود.
این ماشین در لحظهی شروع اجرای بازی بر روی Entry State قرار دارد و بعد به Default State تغییر حالت میدهد. این امر با یک پیکان که از Entry به Default State کشیده شده نمایش داده شده است.
Default State با رنگ نارنجی از سایر stateها متمایز میشود. برای تغییر Default State به یک state دیگر بر روی آن state راست کلیک کرده و گزینهی Set as Layer Default State را انتخاب میکنیم.
برای این که امکان سوییچ کردن از یک state به state دیگر وجود داشته باشد از قابلیتی به نام transition استفاده میشود. به عنوان مثال در صورتی که قصد داشته باشیم در هنگام اجرای بازی امکان سوییچ شدن انیمیشن فعال از TestAnimation1 به TestAnimation2 وجود داشته باشد باید از TestAnimation1 به TestAnimation2 یک transition وجود داشته باشد. این قابلیت در حکم جادهی یک طرفهای بوده که امکان سوییچ انیمیشن فعال را از انیمیشن مبدا به انیمیشن مقصد را فراهم میکند.
برای ایجاد یک transition از یک انیمیشن به انیمیشن دیگر ابتدا بر روی state انیمیشن مبدا راست کلیک کرده و گزینهی Make Transition را انتخاب میکنیم؛ سپس بر روی state انیمیشن مقصد کلیک مینماییم. در این هنگام یک پیکان از state انیمیشن مبدا به state انیمیشن مقصد رسم شده که بیانگر وجود transition از مبدا به مقصد میباشد:
تنظیم پارامترهای controller
بعد از ایجاد transitionهای لازم نسبت به ایجاد و تنظیم پارامترهای controller اقدام میکنیم. پارامتر متغیری است که در انیماتور تعریف شده و به ازای هر transition امکان مقداردهی و یا تعیین شرط برای آن وجود دارد. در این حالت در صورت تغییر مقدار پارامتر، انیمیشن فعال با استفاده از transitionای که شرط پارامتر را دارا است به state مقصد سوییچ میشود.
برای مثال فرض کنید که پارامتری از نوع int و با نام myParameter داریم که در transition انیمیشن TestAnimation1 به TestAnimation2 شرط «برابر بودن با 1» را به آن دادهایم. در این حالت اگر انیمیشن فعال گیمآبجکت TestAnimation1 باشد، با مقداردهی myParameter به عدد 1، transition بین دو انیمیشن فعال شده و انیمیشن فعال به TestAnimation2 سوییچ میشود.
برای افزودن پارامتر به controller از پنجرهی Animator سربرگ Parameters را انتخاب کرده و بر روی آیکون + کلیک کرده و نوع دادهی پارامتر و نام آن را مشخص میکنیم. سپس برای افزودن شرط به transition بر روی آن کلیک کرده و در پنجرهی Inspector در قسمت Conditions شرطهای خود را اضافه میکنیم.
در نهایت برای تغییر پارامترها از طریق کد در یک اسکریپت فیلدی از نوع Animator تعریف کرده و کامپوننت Animator مربوطه را به آن نسبت میدهیم و با استفاده از متدهای Set انیماتور (Set[dataType]) اقدام به تغییر مقدار پارامتر میکنیم. به عنوان مثال:
نکته
امکان تغییر پارامترها در هنگام اجرای بازی از طریق سربرگ Parameters پنجرهی Animator نیز امکانپذیر است. از این امکان برای تست Animator استفاده میشود.
افزودن behavior به stateها
هر state میتواند یک اسکریپت که از کلاس StateMachineBehaviour
ارثبری کرده باشد را بر روی خود پیادهسازی کند. با استفاده از این اسکریپت میتوان تعدادی از متدهای مربوط به state را override و شخصیسازی نمود. برای افزودن یک اسکریپت StateMachineBehaviour به state ابتدا state موردنظر را انتخاب کرده و سپس از پنجرهی Inspector بر روی دکمهی Add Behaviour کلیک میکنیم. در نهایت یک نام برای اسکریپت انتخاب میکنیم.
فایل اسکریپت ساخته شده به صورت پیشفرض دارای متدهای موردنظر و توضیحاتی دربارهی آنها به صورت کامنت است. در این مرحله میتوان متدهای موردنیاز را آنکامنت و استفاده نمود.