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

image

یونیتی و اندروید استودیو هر دو از ابزارهای پیشتاز توسعه محسوب می‌شوند؛ یونیتی در بین موتورهای ساخت بازی و اندروید استودیو در زمینه‌ی ساخت اپلیکیشن‌های اندرویدی.

با وجود این که این دو ساختار و کاربرد کاملا متفاوتی دارند اما نکته‌ی بسیار مهمی وجود دارد که بسیاری از توسعه‌دهندگان به دلیل تجربه نکردن هر دوی این ابزارها آن را نمی‌دانند: یونیتی و اندروید استودیو از تفکر مشابهی برای توسعه بهره برده‌اند.

دانستن این موضوع بسیار مهم است که بینش شی‌گرایانه‌ای که توسعه‌دهندگان اندروید استودیو بر مبنای آن کدنویسی می‌کنند شباهت بسیار زیادی به روند انجام این کار در موتور یونیتی دارد.

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

image

این مقاله را یک دعوت‌نامه برای ورود به دنیای بازی‌سازی یا حداقل آشنا شدن با آن بدانید.

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

شباهت‌های ساختاری

Activity => Scene

در اپلیکیشن‌های اندرویدی مفهومی به نام اکتیویتی وجود دارد. اکتیویتی صفحه‌ای است که اجزای اپلیکیشن بر روی آن چیده شده‌اند؛ یک اپلیکیشن می‌تواند از یک یا چندین اکتیویتی تشکیل شده باشد و بسته به انتخاب‌های کاربر نهایی از اکتیویتی اولیه (لانچر) به اکتیویتی‌های دیگری انتقال صورت پذیرد.

این مفهوم در یونیتی با نام صحنه (Scene) شناخته می‌شود. صحنه‌ی یونیتی یک فایل با فرمت unity است که پس از ایجاد امکان قرار دادن و چینش اجزا درون آن فراهم می‌شود.

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

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

برای اجزایی که در جهان بازی قرار ندارند (مثل UI elementها) شیوه‌ی مکان‌دهی دیگری وجود دارد که بسیار قدرتمند و کاربردی بوده و کاملا قابل مقایسه با نحوه‌ی چینش اجزا توسط فایل layout می‌باشد:

image

مشابه اندروید استودیو برای این که یک صحنه اولین صحنه‌ای باشد که در هنگام باز شدن بازی برای کاربر لود شود (همانند اکتیویتی لانچر) در هنگام build گرفتن از پروژه build index آن را برابر صفر قرار می‌دهیم.

Fragment => Camera

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

View => GameObject

اجزایی که درون یک اکتیویتی (یا به طور دقیق‌تر layout) قرار می‌گیرند view نامیده می‌شوند. viewها انواع مختلفی داشته که بسته به نیاز اپلیکیشن نوع مناسب مورد استفاده قرار می‌گیرد.

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

برای مثال دوربین گیم آبجکتی است که به آن کامپوننت Camera الصاق شده و یک تصویر گیم آبجکتی است که به آن کامپوننت Sprite Renderer (که وظیفه‌ی آن رندر تصاویر است) متصل شده. تنها دلیل تفاوت گیم‌آبجکت‌ها کامپوننت‌های متصل به آن‌ها است. همچنین امکان نوشتن کامپوننت‌های اختصاصی توسط توسعه‌دهنده (به زبان سی شارپ) وجود دارد؛ به عنوان مثال برای پیاده‌سازی هوش مصنوعی خاصی برای حرکت دشمن و…

شی‌گرایی و کدنویسی در دو ابزار

در برنامه‌نویسی اندروید برای کدنویسی viewها ابتدا فیلدی از نوع آن‌ها تعریف کرده (به عنوان مثال TextView myText) و سپس با ارجاع به آی‌دی view آن را به فیلد اشاره می‌دهیم.

یعنی اگر بخواهیم یک TextView که آی‌دی آن برابر با myId است توسط فیلد اشاره داده شود از دستور

TextView myText = findViewById(R.id.myId);

استفاده می‌کنیم. این متد در بین تمام viewهای اکتیویتی جستجو کرده و آدرس نتیجه را درون فیلد قرار می‌دهد.

مشابه این عمل در یونیتی وجود دارد. یعنی اگر بخواهیم به یک کامپوننت اشاره کنیم که گیم آبجکت آن نام مشخصی در صحنه دارد (مثلا MyGameObject) کافی است ابتدا یک فیلد از نوع کامپوننت ایجاد کرده (به عنوان مثال SpriteRenderer mySprite) و سپس با استفاده از دستور

SpriteRenderer mySprite = GameObject.Find("MyGameObject").GetComponent<SpriteRenderer>();

آن را به فیلد متصل کنیم.

سپس با استفاده از dot operator تغییرات دلخواه را بر روی view و یا گیم آبجکت اعمال می‌کنیم.

در SDK اندروید کلاس‌های متناظر تمام viewها از کلاس والد View ارث‌بری کرده‌اند. در یونیتی نیز تمام کلاس‌های متناظر کامپوننت‌ها از کلاس والد GameObject ارث برده‌اند.

هر دوی این ابزارها از متدهای از پیش نوشته شده‌ای استفاده می‌کنند که در اندروید استودیو جزء چرخه‌ی عمر اکتیویتی و در یوتینی جزء چرخه‌ی عمر گیم‌آبجکت به شمار می‌روند.

syntax کدنویسی

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

شباهت‌های رابط کاربری

نمایش فایل‌های پروژه

هر دو ابزار پنجره‌ای اختصاصی برای کاوش فولدر پروژه و فایل‌های موجود در آن به صورت سلسله‌مراتبی دارند:

image

چینش اجزا

عملیات چینش در اندروید استودیو در پنجره‌ی layout و در یونیتی در پنجره‌ی Scene صورت می‌پذیرد. این دو پنجره شباهت‌های زیادی با هم دارند.

image

مشاهده‌ی لیست اجزا

در برنامه‌ی اندروید استودیو لیست تمام viewهای موجود در یک layout در پنجره‌ای با نام Component Tree قرار گرفته است. در یونیتی پنجره‌ای با نام Hierarchy قرار داشته که همین وظیفه را بر عهده دارد:

image

مشاهده‌ی خصوصیات اجزا

در برنامه‌ی اندروید استودیو با کلیک بر روی هر view امکان تغییر مشخصات آن در پنجره‌ی Declared Attributes وجود خواهد داشت.

در یونیتی با کلیک بر روی نام گیم آبجکت در پنجره‌ی Hierarchy یا Scene خصوصیات قابل تنظیم در پنجره‌ای به نام Inspector نمایش داده می‌شوند.

image

مشاهده‌ی خروجی پروژه

برای تست کردن خروجی لحظه‌ای پروژه در اندروید استودیو به یک دستگاه فیزیکی و یا شبیه‌ساز اندروید احتیاج داریم. اما در یونیتی امکان اجرای پروژه در محیط یونیتی وجود دارد که پس از هر بار اجرای بازی خروجی در پنجره‌ی Game قابل مشاهده است. همچنین در صورت نیاز به تست بر روی دستگاه واقعی اپلیکیشنی به نام Unity Remote وجود دارد که پس از نصب و اجرای آن در گوشی و اتصال گوشی از طریق USB Debugging با هر بار اجرای بازی در یونیتی بازی در گوشی واقعی نیز اجرا می‌شود.

حرف آخر

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