آموزش گام به گام ساخت بازی های دو بعدی در یونیتی_آموزش ساخت بازی دو بعدی در یونیتی
«بسم ا… الرحمن الرحیم»
–
مترجم: sajjad3011
آموزش ساخت بازی دو بعدی در یونیتی
به خاطر درخواست زیاد دوستان و همچنین برای پیشرفت خودم تصمیم دارم متون کاربردی برای بازیسازی دو بعدی در یونیتی رو ترجمه کنم.امیدوارم به اذن خداوند،موفق بشم تا خدمتی ناچیز به همه ی دوستان اینترنتی خودم کرده باشم و امیدوارم شما هم تلاش کنید و نمونه بازی های دو بعدی خودتون رو به نمایش بگذارید تا تشویقی بشه برای پیشرفت همه ی بچه های ایران و … .
–
مرحله ی ۱:
یک پرژه جدید new کنید:
۵ تا پوشه animations و prefabs و scenes و scripts و spite-sheets ایجاد کنید برای نظم بیشتر.
مرحله ی ۲ :
این برگه ی اسپرایت (sprite sheet) رو دانلود کنید و دو پوشه ی sprite-sheet ایجاد شده در کادر پروژه اضافه کنید(با ماوس بگیرید و توش رها کنید):
http://s6.picofile.com/file/8187809426/k…_sheet.png
اولین باری که فایل برگه ی اسپرایت رو در پوشه ی sprite-sheet کپی کردید اگه روش کلیک کنید خصوصیاتی در پنجره ی inspector نمایان میشه:
بعضی از این خصوصیات رو بق نیاز باید تغییر بدیم.
‘Sprite Mode’ رو بذارید روی ‘Multiple’ (دلیلش اینه که اسپرایت ما شامل انیمیشن یا چند فریم هست):
نکته:
اگه sprite mode پیدا نشد باید قبلش اسپرایت رو انتخاب کنیم سپس texture type روی sprite بذاریم:
نکته :
اگه پروژه شما سه بعدی بود باید روی حالت دو بعدی تنظیم کنید.
برای این منظور مسیر Edit > Project Settings >Editor رو طی کنید و Mode پیشفرض رو روی ۲d بذارید.
حالا به ویاریشگر اسپرایت (sprite editor) می ریم :
مرحله ی ۳: برش یا slice اسپرایت :
روی slice در sprite editor کلیک کنید :
اگه حالت اتواتیک/Automatic رو بذارید خودش خودکار برش می زنه و اگه حالت
grid بزنید می تونید خودتون برش بزنید.(grid به معنی سیم هست)
گزینه ی pivot به معنی لولا هست.مثل گیم میکر اونجا می تونستید center کنید که لولا روی مرکز اسپرایت باشه.
اینجا هم می تونید bottom و left و right و top right و top left و … بدید که pivot تنظیم بشه.
معمولا خودم روی center میذارم.
وقتی از تنظیمات راضی شدید ‘Apply’ کنید.
نکته : معمولا اسپرایت ها رو بهتره خودتون توسط ابزارهایی مثل Flash یا
Texture Packer پک کنید توی یک تکستچر و بینشون سعی کنید فاصله مناسب
بذارید که یونیتی بتونه خوب شاسایی کنه اونا رو.
ابزار texture packer رو می تونید اینجا مورد تحقیق قرار بدید(اصلا اینم نیاز نیست،با فتوشاپ بهتره کار کنید) :
https://www.codeandweb.com/texturepacker
بعد از apply کردن می بینید اسپرایت توی پنل Project تیکه تیکه میشه به قسمت های دلخواه :
مرحله ی ۴ : ایجاد انیمیشن از برش های Sprite Sheet :
اجازه بدید تا Idle animation (انیمیشن حالت عادی) رو با فریم های ۰ تا ۹
ایجاد کنیم. فریم های دلخواه رو انتخاب کرده و drag کنید به scene.(یعنی
بگیرید با ماوس و توی صحنه رها کنید.scene همون صحنه یا مرحله ی ما هست.
پس از این کار پیامی برای ذخیره ی نام انیمیشن دریافت خواهید کرد. می
تونید اسم انیمیشن رو برای ذخیره وارد کرده و تایید کنید.(پسوند این فایل ،
.anim خواهد بود)
انیمیشن های دیگه رو به ترتیب زیر نام گذاری و فریم گذاری کنید :
walk = frames 10 to 20
hadooken = frames 21 to 31
crouch = frames 32 to 37
jump = frames 38 to 48
پس از عملیات فوق ۵ انیمیشن در پوشه ی project > animation خواهیم داشت. معنیشون فکر کنم این میشه :
idle = ایستادن
walk = دویدون
hadooken = پرتاب نیرو با دست
crouch = خم شدن
jump = پریدن
ادامه:
—–
اگر دقت کنید می بینید که unity، کنترلر های لازم رو در پوشه ی مربوط به هر انیمیشن ایجاد می کنه.
در صورتی که بخواید می تونید کنترل های اضافی رو به دلخواه حذف کنید.
زمانیکه ما یک ‘Master Animation Controller’ برای کاراکتر Ken ایجاد می کنیم فایل های انیمیشن دار(مطابق شکل زیر) رو حذف نکنید.
شما باید همه ی انیمیشن ها رو همچنین در صحنه اضافه کنید. وقتی که اجرا می
گیرد همه ی انیمیشن ها رو یکبار می بینید.همه ی انیمیشن ها رو از صحنه حذف
کنید.
پارامترهای size و filed of view(میدان
دید) و projecttion(حالت ارتوگرافیک=دوبعدی و حالت پرسپکتیو=سه بعدی) و
near(نزدیکی دوربین) رو هم می تونید تنظیم کنید که دوربین اسپرایت رو از
نزدیک تر بگیره.
در ادامه به اذن پروردگار مهربان و عزیز ، تنظیم انیمیشن ها و سوئیچ بینشون رو یاد خواهم داد انشاءا… .
ایجاد کامپوننت player:
یک گیم آبجکت empty ایجاد کنید که برای player استفاده خواهیم کرد.( ‘GameObject > Create Empty’)
نامش را Player بگذارید.
یک کامپوننت Sprite Renderer بدان بیفزایید.
player را در hierarchy انتخاب کرده و روی دکمه ‘Add Component’ کلیک کنید.
حالا باید به این sprite renderer بگید که کدوم اسپرایت رو قراره استفاده کنیم.(فقط یک اسپرایت)
در مثال ما از یکی از اسپرایت های Idle animation استفاده می کنیم.
ما دو روش داریم.
اسپرایت رو از پنل project به پنل Component بکشیم.
روش دیگه اینه که روی دایره کوچیک کنار پارامتر sprite کلیک کنیم و اپرایت دلخواه رو از لیست انتخاب کنیم:
حالا شما یک اسپرایت رو به player اتچ (attach) کردید و در صحنه قابل نمایش هست.
افزودن انیمیشن به player:
ابجکت Player برای مدیریت انییشن های بازیکن نیاز به یک Animator component(کاپوننت انیماتور) داره.
در پنل insector از Player می تونید روی دکمه ی ‘Add Component’ کلیک کنید
و اونو اضافه کنید.(هم می تونید مسیر ‘Miscellaneous > Animator’. رو
طی کنید هم می تونید تایپ کنید animator تا بیاد بعدش از توی لیست انتخابش
کنید)
کامپوننت انیماتور نیاز به یک کنترلر داره که توی پارامتر ‘Controller’ به عنوان وردی باید بهش معرفی کنید.
این پارامتر به انیماتور می گه کدوم انیمیشن باید اجرا بشه.
اجازه بدید بریم تا انیمیشن خودمون رو ایجاد کنیم.
ایجاد یک Animation Controller اصلی :
برای کنترل انیمیشن های مختلف Unity3D دارای قابلیتی به نام Animation
Controller است.(بهش ماشین حالت یا state manager یا state machine هم گفته
شده)
ما می تونیم در پنجره ی انیماتور انیمیشین ها رو با ماوس بگیریم و رها
کنیم و اونا رو مدیریت کنیم و با استفاده از متغیرهایی که ایجاد می کنیم و
بررسی مقدارشون و شرط هایی که میذاریم تعیین می کنیم که کدوم انیمیشن باید
play بشه و کدوم stop .
معمولا وقتی انیمیشن هارو همونطوری که قبلا دیدیم ایجاد کردیم یونیتی خودش
کنترلرهایی رو برای هر انیمیشن در پوشه ی مربوط در کادر پروژه ایجاد می
کنه که اگه نیاز بهشون نباشه حذفشون می کردیم.
تنظیم انیمیشن ها در پنجره ی Animator:
انیمیشن ها رو بگیرید توی پنجره ی انیماتور رها کنید :
تنظیم انیمیشن پیشفرض یا default animation :
این انیمیشن به طور پیشفرض و در حالت عادی(idle) اجرا خواهد شد. در اینجا
ما انیمیشن Idle رو به عنوان انیمیشن Default در نظر می گیریم.
در پنجره ی Animator انیمیشن ها رو اضافه کنید سپس روی انیمیشن idle راست
کلیک کرده و ‘Set As Default’ رو بزنید تا انیمیشن پیشفرض بشه.(رنگ انیمیشن
پیشفرض نارنجی خواهد شد)
سپس بای transition یا ارتباط بین انیمیشن ها رو ایجاد کنید.
همه کار با رات کلیک انجام میشه.روی هر کدم که می خواید راست کلیک کرده و ‘Make Transition’ رو انتخاب کنید.
از انیمیشن idle به انیمیشن walk و بلعکس فلش(جهت) ایجاد کنید(تا بتونیم از هرکدوم به دیگری سوئیچ کنیم):
باقی ارتباطات رو طبق شکل زیر ایجاد نمایید :
سعی کنید در ایجاد ارتباط های خود اندیشه کنید.
تعریف پارامترها و متغیرهای شرطی برای سوئیچ بین انیمیشن ها و تغییر وضعیف در پنجره ی انیماتور:
برای ایجاد متغیرهای دلخواه در قسمت ‘Parameters’ روی نماد '+' کلیک کرده و یک متغیر از نوع ‘Int’ با نام ‘state’ ایجاد کنید.
تنظیم transition conditions یا شرط سوئیچ بین انیمیشن ها:
حالا به انیماتور باید بگیم که بر حسب مقدار تغیر ‘state’ چه کاری انجام
بده.در اصطلاح می گیم انیماتور داره گوش یا listen می کنه به state.
(این فراید یا پروسه یکم خسته کننده هست و نیاز به مقدار کمی زمان برای
بررسی دقیق reaol-Time داره تا ببینیم همه چی درست داره انجام میشه یا خیر)
قبل از هرچیز بذارید مقدار مربوط به سوئیچ برای هر انیمیشن رو به طور دلخواه در نظر بگیریم :
ken_idle = 0
ken_walk = 1
ken_crouch = 2
ken_jump = 3
ken_hadooken = 4
سپس باید روی خطوط transition(انتقال) در پنجره ی Animator کلیک کنیم(فلش های ارتباطی سفید رنگ) و خصوصیت state خودمون رو تنظیم کنیم.(در اصطلاح می گیم map کنیم)
روی خط انتقال از حالت ken_idle به ken_walk کلیک کنید(وقتی انتخاب بشه رنگش آبی میشه)
به inspector نگاه و به چک باکس ‘Atomic’ توجه نمایید. دقت داشته باشید اگه این چک باکس فعال باشه بین دو انیمیشن وقفه ای رخ نمیده یا انتقال بین این دو قطع نخواهد شد.در صورت نیاز بعدا به آن خواهیم پرداخت،اما فعلا به حالت فعال آزادش بذارید.
** نکته : بعضی اوقات محتوای این سربرگ با انتخاب transision ها درست نمایش داده نمی شه.چنانچه ‘conditions’(شرط ها) رو خوب نمی بینید پنل رو reSize یا بزرگ کنید.
در سربرگ فرعی ‘Conditions’ شرط ها رو تعریف می کنیم. مثلا می گیم مقدار متغیر state برابر(equal) با فلان اگه بود کاری انجام بشه یا اگه مقدارش بیشتر یا کمتر از … بود فلان کار رو کنه و الی آخر… .
شرط ها رو مثل عکس زیر ایجاد کنید :
مقادیر کلیدی شرطی ما به این صورت خواهند بود :
ken_idle to ken_crouch when state equals 2
ken_idle to ken_jump when state equals 3
ken_idle to ken_hadooken when state equals 4
ken_walk to ken_idle when state equals 0
ken_walk to ken_crouch when state equals 2
ken_walk to ken_jump when state equals 3
ken_crouch to ken_idle when state equals 0
ken_jump to ken_idle when state equals 0
ken_hadooken to ken_idle when Exit Time
Exit Time به معنی اینه که وقتی انیمیشن به پایان رسید به حالت عادی یا idle بره.
یعنی اگه توی حالت فلان بود و متغیر state مقدارش دستکاری شد برو به فلان حالت.
سوئیچ بین انیمیشن ها در زمان اجرا:
از اونجایی که یونیتی خیلی عالی هست به ما این اجازه رو میده که به صورت real-time بدون نیاز به ورودی keyboard بین مقادیر متغیر state تجدید نظر کنیم.(جلوتر روی آن بحث خواهیم کرد)
به سادگی بازی رو اجرا کرده و در پنجره ی Animator پارامتر ها رو به هر مقداری که می خواید تغییر داده و شاهد نتیجه باشید.
بخش آخر: سوئیچ بین انیمیشن ها از طریق فشردن کلیدهای کیبورد
در بخش های قبلی یادگرفتیم انیمیشن های دو بعدی player رو با استفاده از
sprite و sprite editor ایجاد کنیم و همینور کنترلر انیمیشن و سازماندهی
انیمیشن ها در پنجره ی Animator و همچنین تنظیم شرط یا Condition ها و
پارامترهای انیمیشن رو.
حالا سعی می کنیم با کدنویسی این بخش رو به پایان ببریم.در این بخش قصد
داریم کدهای لازم برای بکار گیری کیبورد جهت سوئیچ بین انیمیشن های مختلف
رو تمرین کنیم.
نکته ی مهم :
قبل از ادامه ، انیمیشن crouch رو از پنجره ی Project انتخاب کنید و چک
باکس Loop Time رو در کادر خصوصیات inspector غیر فعال کنید(این کار از
تکرار انیمیشن جلوگیری می کنه). اینکار باعث میشه کاراکتر ken از حالت
crouching (خیزان) و ادامه ی حالت standing up (ایستاده) Stop کنه.
در پنجره ی Animator یک transition جدید از انیمیشن های ken_crouch به ken_walk با شرط ‘state Equals 1′ ایجاد کنید.
افزودن پس زمینه یا Background Graphic به صحنه :
در پنجره ی Project از پوشه ی spritesheets ، تکستچر ken-sprite-sheet
را باز کنید و 'ken-sprite-sheet_49' رو که یک background graphic هست
انتخاب کنید و با ماوس بگیرید و Drag کنید توی صحنه.سپس توی صحنه انتخابش
کنید و خصوصیت Order in layer رو بذارید روی منفی یک(-۱) تا زیر لایه های
دیگه قرار بگیره.(order در اینجا همون مفهوم depth یا عمق در گیم میکر رو
داره) در یونیتی هر چی عمق یک تکستچر کمتر باشه در لایه ی زیرتر قرار می
گیره . پس عمق پس زمینه باید کتر از بقیه باشه.
position رو روی ۰, ۰, ۰ تنظیم کنید.
کلا تصویر بک گراند رو طوری تنظیم کنید که دقیقا جلوی دوربین و پشت اسپرایت های دیگه باشه و دوربین صحنه رو کامل نمایش بده.
سپس screen resolution رو روی ۱۶:۹ تنظیم کنید(در سربرگ game و از لیست پایین رونده):
این رزولوشن فقط یه مثال بود و روی گوشی های مختلف باید تنظیم نزدیک تر رو انجام بدید.
ایجاد C# Script برای player:
یک اسکریپت سیشارپ(با راست کلیک در کادر پروژه) ایجاد کنید و اونو به PlayerController تغییر نام بدید.
کد زیر رو Copy Paste کنید داحل اسکریپت و ذخیره کنید:
//PlayerController.Cs
using UnityEngine;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float walkSpeed = 1; // player left right walk speed
private bool _isGrounded = true; // is player on the ground?
Animator animator;
//some flags to check when certain animations are playing
bool _isPlaying_crouch = false;
bool _isPlaying_walk = false;
bool _isPlaying_hadooken = false;
//animation states - the values in the animator conditions
const int STATE_IDLE = 0;
const int STATE_WALK = 1;
const int STATE_CROUCH = 2;
const int STATE_JUMP = 3;
const int STATE_HADOOKEN = 4;
string _currentDirection = "left";
int _currentAnimationState = STATE_IDLE;
// Use this for initialization
void Start()
{
//define the animator attached to the player
animator = this.GetComponent<Animator>();
}
// FixedUpdate is used insead of Update to better handle the physics based jump
void FixedUpdate()
{
//Check for keyboard input
if (Input.GetKeyDown (KeyCode.Space))
{
changeState (STATE_HADOOKEN);
}
else if (Input.GetKey ("up") && !_isPlaying_hadooken && !_isPlaying_crouch)
{
if(_isGrounded)
{
_isGrounded = false;
//simple jump code using unity physics
rigidbody2D.AddForce(new Vector2(0, 250));
changeState(STATE_JUMP);
}
}
else if (Input.GetKey ("down"))
{
changeState(STATE_CROUCH);
}
else if (Input.GetKey ("right") && !_isPlaying_hadooken )
{
changeDirection ("right");
transform.Translate(Vector3.left * walkSpeed * Time.deltaTime);
if(_isGrounded)
changeState(STATE_WALK);
}
else if (Input.GetKey ("left") && !_isPlaying_hadooken)
{
changeDirection ("left");
transform.Translate(Vector3.left * walkSpeed * Time.deltaTime);
if(_isGrounded)
changeState(STATE_WALK);
}
else
{
if(_isGrounded)
changeState(STATE_IDLE);
}
//check if crouch animation is playing
if (animator.GetCurrentAnimatorStateInfo(0).IsName("ken_crouch"))
_isPlaying_crouch = true;
else
_isPlaying_crouch = false;
//check if hadooken animation is playing
if (animator.GetCurrentAnimatorStateInfo(0).IsName("ken_hadooken"))
_isPlaying_hadooken = true;
else
_isPlaying_hadooken = false;
//check if strafe animation is playing
if (animator.GetCurrentAnimatorStateInfo(0).IsName("ken_walk"))
_isPlaying_walk = true;
else
_isPlaying_walk = false;
}
//--------------------------------------
// Change the players animation state
//--------------------------------------
void changeState(int state){
if (_currentAnimationState == state)
return;
switch (state) {
case STATE_WALK:
animator.SetInteger ("state", STATE_WALK);
break;
case STATE_CROUCH:
animator.SetInteger ("state", STATE_CROUCH);
break;
case STATE_JUMP:
animator.SetInteger ("state", STATE_JUMP);
break;
case STATE_IDLE:
animator.SetInteger ("state", STATE_IDLE);
break;
case STATE_HADOOKEN:
animator.SetInteger ("state", STATE_HADOOKEN);
break;
}
_currentAnimationState = state;
}
//--------------------------------------
// Check if player has collided with the floor
//--------------------------------------
void OnCollisionEnter2D(Collision2D coll)
{
if (coll.gameObject.name == "Floor")
{
_isGrounded = true;
changeState(STATE_IDLE);
}
}
//--------------------------------------
// Flip player sprite for left/right walking
//--------------------------------------
void changeDirection(string direction)
{
if (_currentDirection != direction)
{
if (direction == "right")
{
transform.Rotate (0, 180, 0);
_currentDirection = "right";
}
else if (direction == "left")
{
transform.Rotate (0, -180, 0);
_currentDirection = "left";
}
}
}
}
یک ابجکت empty به نام ‘Floor’ برای زمین ایجاد کنید و یک کالیدر دو بعدی از مسیر Physics2D > Box Collider 2D بهش بدید تا player روی اون بتونه بایسته.
افزودن RigidBody2D و Collider به Player:
یک فیزیک دو بعدی به کاراکتر player بدید.(از مسیر Physics2D > Rigid Body 2D ).
بقیه تنظیمات رو به حالت پیشفرض بذارید باشه.
اگه همه چیز رو درست تنظیم کرده باشید باید از نتیجه ی کار خودتون خوشتون
بیاد.(گاهی هم به علت برخی زا اشتباهات ممکنه دچار خطاهایی بشید که به
error ختم میشن)
کلیدهایی که کدنویسی کردیم عبارتند از :
Up = Jump
Left/Right = Walk
Down = Crouch
Space Bar = Hadoooooooken
نکته ی مهم : در آموزشی که دادیم ممکن است چار مشکلاتی شوید که نتوانید آن را حل کنید.سعی کنید در اون مورد بحث و پرس و جو کنید.
آموزش سه بعدی گذاشتن برای بازی های ساده مشکلی نیست.اما برای ساخت بازی
های خوب مشکل اصلی انیمیشن و مبحث Rigging(استخوان های انیمیشن داری که هر
مدلی رو بتونیم سوارش کنیم)هست. Rigging با دست کار بسیار مشکلی هست و
بسیار اذیت کننده و خسته کننده هست.به همین دلیل فعلا اون بخش اولویت نداره
و ممکنه بعا بی انگیزه بشید.پس تا یه چیزی رو خوب تمرین نکردید و مسلط
نشدید سراغ هدف دیگه ای نرید.
راستی یه نکته:کیا آموزش رو انجام دادن؟ به خطا برنخوردید؟ من خودم هنوز یه مشکلی دارم : وقتی RigigdBody میدم کاراکتر میره هوا
—
جلوگیری از به هوا رفتن کاراکتر با غیر فعال کردن گزینه ی Apply Root Motion در کامپوننت Animator از Player:
اگر دیدید کاراکتر به هوا میره پارامتر Apply Root Motion رو برای کامپوننت Animator غیر فعال کنید.