آموزش یونیتی unity قسمت سوم

1395/1/12 آقای پیر 2645

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

از جلسه ی پیش مطمئنا به خاطر دارید که ما کاراکترمون رو ساخته بودیم، و توسط اسکریپتی، تونسته بودیم که با کلید های کیبورد کاراکترمون رو (که همون کپسول باشه) به حرکت دربیاریم. و حتما به خاطر دارید که یک مشکل وجود داشت، و اون اینکه کاراکتر به سمت بالا و پایین (درواقع مثبت و منفی محور z) هم حرکت میکرد، و این باعث میشد که کاراکترمون از سطح زمین سقوط کنه پایین؛

در این قسمت باید این معضل رو برطرف کنیم، اما قبل از اون، میبایست متوجه بشیم که کد فعلی چه کاری انجام میده دقیقا

بنابراین باز دیگه وارد محیط یونیتی بشید، پروژه ای که ساخته بودیم رو باز کنید، و روی اسکریپتمون که در پوشه ی Scripts قرارش داده بودیم و براش نام movement انتخاب کرده بودیم دابل کلیک کنید تا محیط برنامه نویسی MonoDevelop رو برامون باز کنه و بتونیم کد ها رو مشاهده کنیم:

آموزش یونیتی

هر کد سی شارپ در یونیتی، تابعی به اسم Update داره که در هر فریم فراخوانی میشه، یعنی این تابع پشت هم در حال فراخوانی هست.

اگه یادتون باشه ما به کاراکترمون؛ یک کامپوننت به اسم Character Controller اضافه کرده بودیم،

ما در خط دهم این کد، آمدیم و این کامپوننت رو از توی کاراکترمون گرفتیم و اسمش رو گذاشتیم Controller.

حالا این کنترلر به ما یک سری امکانات میده، یعنی میتونیم با این کنترلر کاراکترمون رو حرکت بدیم، چک کنیم ببینیم روی زمین هست یا نه، و...

ما میخوایم صرفا در صورتی که کاراکتر بر روی زمین هست، بتونه بپره و راه بره، درسته؟ چون مثلا در غیر این صورت میتونه توی هوا هم بپره باز!

یا وقتی پریده، توی هوا راه بره! ما این رو نمیخوایم، پس اول باید چک کنیم که آیا کاراکتر روی زمین هست یا خیر، و برای چک کردن این خیلی ساده، شرط

if (controller.isGrounded)

رو قرار میدیم.

دستور بعدی یعنی:

moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

یه وکتور 3 هست (بردار با سه پارامتر x و y و z) که جهتی که در هر لحظه کاراکتر باید راه بره رو مشخص می کنه، حالا چطور؟ فرض کنید از بالا دارید به بازیتون نگاه می کنید نه از کنار.

یعنی ویوتون یه همچین چیزی باشه:

آموزش یونیتی

ما در واقع میخوایم در حالت کلی کاراکتر بتونه در راستای محور x و z حرکت کنه (البته توی این بازیِ خاص که ما داریم میسازیم میخوایم فقط در راستای x حرکت کنه ، اما حالت کلی اینه که کاراکتر بتونه در راستای x و z حرکت کنه)

پس اگر مثلا بخوایم با یک بردار جهت حرکت کاراکتر رو مشخص کنیم که سه تا مشخصه ی X و Y و Z داره، مطمئنا باید مختصه ی Y همیشه صفر باشه (چون نمیخوایم کاراکتر بره توی زمین) و دو مشخصه ی دیگه بر اساس کلید هایی که ما روی صفحه کلید میزنیم مقدار دهی بشن.

خوشبختانه یونیتی همه چیز رو برای ما آماده کرده، و ما برای اینکه بفهمیم یه کلیدی زده شده یا نه، میتونیم از دستورهای از پیش تعیین شده استفاده کنیم:

آموزش یونیتی

دستورات

Input.GetAxis("Horizontal")

و

Input.GetAxis("Vertical")

به ترتیب میان کلید های Horizontal و Vertical رو بررسی می کنن، وقتی کلید ها در جهت مثبت زده شد، مقدار +1 و اگر کلید ها در جهت منفی زده شد، -1 و در حالت عادی وقتی کلیدی زده نشده، مقدار 0 رو برمیگردونن،

یعنی اگر ما همچین کدی بنویسیم:

moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));

دقیقا نتیجه ای که میخوایم، یعنی برداری که مشخص میکنه کاراکتر باید کدوم طرفی بره رو بهمون خواهد داد.

اما ما در بازیِ خودمون چی میخوایم؟!

میخوایم کاراکتر همیشه به سمت راست محور x حرکت کنه! چه کلیدی زده بشه و چه نه،

بنابراین با اینکه این خط کد رو توضیح دادم، اما ما در بازی خودمون بهش نیازی نداریم، این خط رو کامنت کنید ( با گذاشتن // اول خط) و یا کلا حذفش کنید و این خط رو جایگزین کنید:

moveDirection = new Vector3(1f,0,0);

دلیلش هم واضحه، ما صرفا میخوایم کاراکتر بره جلو؛ و ما فقط پرش و نشستنش رو کنترل کنیم، پس صرفا یه بردار در جهت x ایجاد می کنیم.

اما خط بعدی، یعنی:

moveDirection = transform.TransformDirection(moveDirection);

جهت به دست اومده از وکتور3 رو تبدیل میکنه به جهت در فضای کلی بازی، که بتونه برای مقدار دهی مکان جدید کاراکتر بر اساس این جهت استفاده بشه.

در خط بعد هم هربار بردار به دست اومده رو در یک متغیر به اسم speed ضرب می کنیم تا مقدار سرعش قابل کنترل باشه و بشه با تغییر مقدار متغیر speed سرعت کاراکتر رو هم تغییر داد.

در نهایت میخوایم وقتی کلید پرش زده شد، کاراکتر به سمت بالا بره، بنابراین شرط:

if (Input.GetButton("Jump"));

رو قرار میدیم، به این معنی که اگر، کلید پرش زده شد، مقدار Y متغیر movedirection رو برابر یک مقدار مشخصی قرار بده،

در انتها هم برای شبیه سازی جاذبه، هربار بایک ضریبی از مقدار y بردار movedirection کم می کنیم.

در واقع انگار در هر فریم داریم کاراکتر رو به سمت 0 در محور y ها می کشونیم.

توجه کنید که ضریب

Time.deltaTime

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

و در نهایت در خط آخر، کاراکترمون رو با دستور

controller.Move(moveDirection * Time.deltaTime);

در جهت برداری که مقدار دهیش کردیم حرکت میدیم.

ما در بازی خودمون میخوایم که کاراکتر در جهت راست حرکت کنه همیشه و با کلید C بشینه و با کلید X بپره، این کد رو جایگزین کدِ فعلی کنید:

using UnityEngine;
using System.Collections;
public class movement : MonoBehaviour {
  public float speed = 6.0F;
  public float jumpSpeed = 8.0F;
  public float gravity = 20.0F;
  private Vector3 moveDirection = Vector3.zero;
  private CharacterController controller;
  
  private float height=2f;
  private float Sit=1.3f;
  void Start()
 {
    controller = GetComponent();
 }
  void Update(){
    
    if (controller.isGrounded)
    {
      moveDirection = new Vector3(1f,0,0);
      moveDirection = transform.TransformDirection(moveDirection);
      moveDirection *= speed;
      if (Input.GetKeyDown(KeyCode.X()
      }
        moveDirection.y = jumpSpeed;  
 }
      else if(Input.GetKeyDown(KeyCode.C))
    {
        StartCoroutine(SitDown)();
      }
      
   }
    moveDirection.y -= gravity * Time.deltaTime;
    controller.Move(moveDirection * Time.deltaTime);
  }
  IEnumerator SitDown()
  {
    GetComponent().height=Sit;
    yield return new WaitForSeconds(1f);
    GetComponent().height=height;
  }
}

کدتون رو ذخیره کنید و بازی رو اجرا کنید، میبینید که کاراکتر به خوبی به سمت راست داره حرکت می کنه و همینطور با زدن کلید C ارتفاعش کم میشه و با زدن X میپره، و این خیلی عــــالیه!

اما مشکل اینه که دوربین دنبالش نمیره!

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

امیدوارم این قسمت مفید بوده باشه.

دانلود

دانلود PDF قسمت سوم آموزش Unity

قسمت بعدی

قسمت چهارم آموزش یونیتی Unity