ساختن کنترلر دو بعدی برای بازی های RPG در یونیتی

مدتی میشه که یکی از اسباب بازی های جدیدم، یعنی موتور بازی‌سازی یونیتی رو با جدیت بیشتری دارم دنبال میکنم و چیزای جالبی هم ازش یاد گرفتم. همینطور باعث هم شده دوباره کمی کد بزنم و این داستانها.

یکی از سبکهای مورد علاقه من در بازی‌سازی، سبک Role Playing عه که در این سبک، شما در واقع نقش ایفا می‌کنید، نقش هایی که به شما محول شده و یا این که شما هم میتونید در شکل‌گیری نقش دخیل باشید. بازی‌هایی مثل Elder Scrolls از این دست بازی ها هستند. چندی پیش، با یک ابزار آشنا شدم به اسم RPG Maker که به شما اجازه ساخت این دست بازی ها رو بدون کد زدن میده. اما یک مساله مهمی که احتمالا باهاش روبرو خواهید شد، اینه که این ابزار شدیدا محدوده و به سختی میشه شخصی‌سازیش کرد. به همین خاطر، سعی کردم دنبال این برم که یاد بگیرم چطور یک RPG دو بعدی ساده رو بسازم (حتی شده در حد کنترل کرکتر اصلی!).

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

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

برنامه نویسی

برای کنترل کردن کرکترها در بازی، نیاز به کدی داریم که بتونه دیتا رو از کی‌برد، ماوس، صفحه لمسی و … دریافت کنه و حرکتی که مد نظر داریم رو برای ما، انجام بده. این حرکت میتونه صرفا جابجایی باشه، میتونه هم حرکت و انیمیشن با هم باشه. برای این که کد کامل باشه و بازی حرفه‌ای به نظر برسه، بهتره که انیمیشن هم لحاظ کنیم.

کدی که من نوشتم به این شکله :

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : Entity {

    private Animator anim; 

	// Use this for initialization
	void Start () {
        anim = GetComponent<Animator>(); 
	}
	
	// Update is called once per frame
	void Update () {
		if(Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)){
			GetComponent<Rigidbody2D>().transform.position += Vector3.up * speed * Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.down * speed *Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.left * speed * Time.deltaTime; 
		}
		if(Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow) )
        {
			GetComponent<Rigidbody2D>().transform.position += Vector3.right * speed * Time.deltaTime; 
		}

        anim.SetFloat("MoveX", Input.GetAxis("Horizontal"));
        anim.SetFloat("MoveY", Input.GetAxis("Vertical")); 
	}
}<span id="mce_marker" data-mce-type="bookmark" data-mce-fragment="1">​</span>

این کد نشون میده که کلاس PlayerController از کلاس دیگری به اسم Entity داره ارث بری میکنه. تنها چیزی که در Entity تعریف شده، یک متغیر برای سرعت کرکتره. البته، سایر ویژگی هایی که نیاز داریم تا در تمام کرکترها (چه Player و چه NPC ) به کار ببریم رو میتونیم در Entity بگنجونیم.

در Update اومدیم بهش گفتیم که اگر ورودی از کلیدهای خاصی بوده، با سرعت مشخصی در جهتهای مشخص، حرکت کنه. متغیر speed هم یک متغیر public بوده که در Entity تعریف کردیم. در انتها هم گفتیم که دو متغیر ممیز شناور برای حرکت در محور X و Y نیاز داریم که با Animator Controller هماهنگ باشن. این میشه کل چیزی که در متد Update داریم.

در متد اول، یعنی Setup هم صرفا به کد گفتیم که انیماتور رو از خود شیء Player بخونه و لود کنه. پس ما نیاز داریم که خودمون یک انیماتور براش بسازیم.

چطور این کد رو آزمایش کنیم؟

آزمایش کردن این کد، هیچ کاری نداره. چون کل انیمیشن و … رو در گیتهاب قرار دادم (لینک) و میتونید از گیتهاب دانلودش کرده و تست کنید. به زودی هم، این ابزار رو به صورت یک prefab برای یونیتی منتشر میکنم که بتونید مستقیما از همین دیزاین و انیمیشن، بدون چسبوندنشون به هم، استفاده کنید.

موفق باشید 🙂

Share