بهبود کارایی در یونیتی

اموزش بازی سازی با موتور یونیتی

بهبود کارایی در یونیتی

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

الگوریتم و ساختمان داده ها

وقتی صحبت از کارایی بازی میشه مهمترین نقش رو دانش برنامه نویس درباره کدهای بهینه و ساختمان های داده داره.

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

  • لیست ها
  • لیست های پیوندی
  • هش مپ ها
  • درخت ها
  • صف ها
  • پشته ها
  • مرتب سازی ( درجی،حبابی،…)

ریاضیات

دنیای ریاضیات خیلی بزرگتر از اونه که بخوایم تو این مقاله پوشش بدیم. اما ریاضیات برای کارایی خیلی مهمه.

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

مش ها

یک چیزی که میشه به اسونی یادش گرفت بحث بهینه سازی مش هاست.

هنگام ساخت بازی ، ممکنه کلی مدل سه بعدی تو صحنه داشته باشیم. همه این مدل ها از چیزهایی به اسم مش درست شدن. یک مش از کلی مثلث درست شده. هرچی تعداد مثلث ها بیشتر باشه ، تعداد FPS ها کمتر میشه بنابراین خیلی مهمه که تعدادشون تا حد ممکن کم باشه.

مثلا کارکتر هیولا میتونه با 4000 مثلث خوب به نظر برسه . احتیاجی نیست که از یک میلیون مثلث استفاده بشه !
تقریبا اکثر نرم افزارای مدل سازی 3 بعدی ، ابزار بهینه ساز مش رو دارن بنابراین وظیفه شماست ازش استفاده کنین.

وقتی که هیچ راهی نیست مثلثاشو کم کنین ، بازم یک اپشن دیگه وجود داره : LOD ( Level of Detail) یا سطح جزئیات
مفهوم LOD سادست : وقتی یک مش به اندازه کافی از دوربین دوره ، جوری تغییر میکنه که مثلث های کمتری داشته باشه. کاربر متوجه این تفاوت نخواهد شد چون به اندازه کافی کدل از دوربین دوره .
یونیتی از این قابلیت پشتیبانی مکینه . ممکنه یروزی به دردتون بخوره.

ذخیره سازی GetComonent

همونطور که * قبلا گفتیم *دسترسی به اجزای یک شی معمولا با تابع GetComponent انجام میشه . هزینه اجرای این تابع زیاده . به مثال زیر دقت کنین :

این یک مثال خیلی بد بود چون این تابع یکبار تو هر update فراخوانی میشه ( حدود 60 بار در ثانیه). میشه خیلی راحت با نوشتنش مثه زیر بهبودش بدیم و از هزینه هاش کم کنیم :

این تابع تاحدودی بهتره . دقیقا همون کار قبلی رو انجام میده ولی با هزینه کمتر چون فقط یکباز همون ابتدا فراخوانی میشه.

استفاده از میانبر های یونیتی

یونیتی برای راحتی کاربراش راهی برای دسترسی بعضی اجزا استاندارد فراهم کرده که از GetComponent استفاده نکنین . مثل :

  • Transform
  • GameObject

اینطوری استفاده میشن :

کد بالا هم هزینه خیلی زیادی داره . چون در واقع کاری که انجام میده اینه :

هرچند که شبیه این نوشته نشده اما بازم هربار از این تابع استفاده میکنه .

بهترین کار نوشتنش به این صورته :

GUI ها

وقتی از gui ها استفاده میکنین ، راه ساده تر استفاده از کلاس GUILayout بجای GUI هست . ناراحت کنندش اینجاس که این کلاس سرعتش از GUI خیلی کمتره بنابراین بهتره بازم فکر کنین که ایا ارزشش رو داره یا نه ؟

شیدر ها

شیدر ها میتونن کارت گرافیک رو دیوونه کنن. مگر اینکه شما متخصص شیدر باشین! بنابراین بهتره فقط از شیدر های خود یونیتی استفاده کنین.
در کنار اینا ، یونیتی شیدر هایی تحت عنوان ‘Mobile’ داره که مخصوص موبایل طراحی شدن اما میتونن کارایی رو تو کامپیوتر های معمولی بهبود بدن.

ایجاد سایه

وقتی میخوایم تو بازیمون سایه درست کنیم چیزی که همون اول به ذهنمون میرسه اینه :
هربار :

  1. لامپ هارو تو موقعیت هایی قرار بدیم.
  2. صحنه رو بسازیم.
  3. سایه ایجاد کنیم.

خب اینکار خیلی پرهزینس و هی تکرار میشه. اینجاست که ابزار Lightmapping مثه همون ذحیره سازی که بالا استفاده کردیم به کمکمون میاد. یکبار سایه هارو حساب میکنه و اونارو روی تکسچر ها اجرا میکنه . بنابرای نیازی نیست هردفعه محاسبه بشه . و یک بهبود بزرگ تو کارایی بوجود میاره .

امکانات بیشتری هم وجود داره با یکم گشتن تو یونیتی میتونین بهترینشو برای خودتون انتخاب کنین.

لامپ های پویا

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

تخصیص منابع

به کد زیر یک نگاهی بندازین :

تو هر اپدیت یک شی جدید از کلاس someclass ساخته میشه و فضایی براش تو حافظه در نظر گرفته میشه . زمانی که ازش دیگه استفاده نمیشه ، حافظه رو دوباره ازاد میکنه.زمانی که این عمل خیلی تکرار بشه میتونه هزینه سنگینی داشته باشه .

البته خیلی دلایل و کارای پس زمینه دیگه ای هم انجام میشن بنابراین بهتره تو خاطرتون باشه که از new کردن هرچی کمتر استفاده بشه بهتره.

بجاش از همچین کدی استفاده کنین :

خلاصه

کارایی یکی از مهمترین مشکلاتی هست که دنیای کامپیوتر همیشه باهاش سروکله میزنه.

مباحثی که گفته شد از ساده ترین راه ها بودن ولی بدونین کلی راه های ریاضی و الگوریتم های خفن برای بهبود کارایی وجود داره .

بنابراین هرچقدر میتونین درباره این موضوعات مطالعه کنین تا بازی های بهتری بسازین.

منابع : Noobtuts