کار با لیدربورد - Unity

در این مستند ما نحوه ساخت رویداد (Event) و ارسال آن به سرور و دیدن نتیجه‌ی آن در لیدربوردهای اپلیکیشن را خواهیم دید.

پیش‌نیازها

  1. در صورتی که با سرویس مرکز بازی آشنایی ندارید، به معرفی سرویس مرکز بازی مراجعه کنید.
  2. در صورتی که هنوز در پنل توسعه‌دهنده خود تنظیمات لازم برای مرکز بازی را انجام نداده‌اید، به تنظیمات پنل مراجعه کنید.
  3. در صورتی که هنوز SDK یونیتی را راه‌اندازی نکرده‌اید، به راه‌اندازی SDK بکتوری در یونیتی مراجعه کنید.

ارسال یک رویداد (Event)

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

1. استفاده از لیست مقادیر

در این روش شما لیستی از key-valueها تولید کرده و به عنوان داده رویداد، به تابع ارسال یک رویداد، پاس می‌دهید. کد زیر نمونه‌ای از این روش می‌باشد:

// Step 1: Creating parameters for GameOver event
List<BacktoryGameEvent.FieldValue> fieldValues = new List<BacktoryGameEvent.FieldValue>()
{
	new BacktoryGameEvent.FieldValue("gold", 100),
	new BacktoryGameEvent.FieldValue("time", 200)
};

// Step 2: Creating GameOver event and filling its data
BacktoryGameEvent backtoryGameEvent = new BacktoryGameEvent()
{
	Name = "GameOver",
	FieldsAndValues = fieldValues
};

// Step 3: Sending event to server
backtoryGameEvent.SendInBackground(backtoryResponse => {
	// Checking callback from server
	if (backtoryResponse.Successful)
	{
		Debug.Log("saved event successfully");
	} 
	else 
	{
		// do something based on BactoryResponse.Code
	}
});

همانطور که در درخواست بالا می‌بینید ما یک رخداد GameOver با زمان ۲۰۰ و طلای ۱۰۰ ارسال کردیم. در صورتی که تمایلی به انجام کاری در callback ندارید کافیست آن را null پاس بدهید. یعنی:

backtoryGameEvent.SendInBackground(null);

2. استفاده از یک شیء جدید

در صورتی که مدل لیست مقادیر key-value را نمی‌پسندید و دوست دارید کمی شیءگراتر (Object-Oriented) باشید می‌توانید کلاس Event بکتوری را گسترش (Extend) دهید، منطق مورد نظر خود را به آن اضافه کنید و توابع سازنده (Constructor) دلخواه جهت سهولت استفاده به آن اضافه کنید.

برای مثال رخداد GameOver در مثال قبل به شکل زیر خواهد بود:

public class GameOverEvent : BacktoryGameEvent {

   	[EventName]
	public const string EventName = "GameOver";

	[FieldName("gold")]
	public int GoldValue { get; set; }

	[FieldName("time")]
   	public int TimeValue { get; set; }

	public GameOverEvent(int goldValue, int timeValue)
	{
		GoldValue = goldValue;
		TimeValue = timeValue;
	}
}

همانطور که می‌بینید چند annotation بر روی خصوصیات کلاس، یک کد زیباتر و شکیل‌تر معادل با کد روش اول، تولید می‌کند. این annotationها عبارتند از:

ارسال این رخداد مانند روش اول خواهد بود، زیرا رخداد GameOverEvent فرزند BacktoryGameEvent است و توابع آن را به ارث می‌برد. پس کد زیر کار ارسال را انجام خواهد داد:

// Step 1 & 2: Create event and fill it
GameOverEvent gameOverEvent = new GameOverEvent(100, 200);

gameOverEvent.SendInBackground(backtoryResponse => {
	// Checking callback from server
	if (backtoryResponse.Successful)
	{
		Debug.Log("saved event successfully");
	} 
	else 
	{
		// do something based on BactoryResponse.Code
	}
});

بروز خطا

در صورت بروز خطا در ارسال رخداد عبارت backtoryResponse.Successful برابر false خواهد بود، و backtoryResponse.Code نوع خطا را مشخص می‌کند که یکی از مقادیر زیر است:

Tables Description
200-OK Event sent successfully
417-Incorrect event data Event data is incorrect
400-Bad Request EventName or fieldName is null
500-Internal Server Error Data access was unsuccessful
503-Service Unavailable Backtory is unavailable right now

ساخت شیء لیدربورد در SDK

برای آنکه بتوانید به یک لیدربورد در بکتوری اتصال پیدا کنید و اطلاعات آن را از سرور دریافت کنید باید از کلاس BacktoryLeaderBoard در SDK استفاده کنید.

برای ساخت لیدربورد دو روش دارید:

۱. یک شیء از کلاس BacktoryLeaderBoard ساخته و شناسه لیدربورد را به آن پاس دهید. به صورت زیر:

BacktoryLeaderBoard topPlayers = new BacktoryLeaderBoard("576d4a33e4b050913524162c");

۲. کلاس BacktoryLeaderBoard را گسترش دهید. مانند زیر:

public class TopPlayersLeaderBoard : BacktoryLeaderBoard {

	[LeaderboardId]
	public const string Id = "576d4a33e4b050913524162c";
}

و هر جا که لازم بود از آن یک نمونه به صورت زیر بسازید:

TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();

در هر یک از دو صورت بالا شما می‌توانید سه عمل مهم با لیدربورد انجام دهید:

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

توجه: این سرویس تنها برای کاربر فعلی گوشی کاربرد دارد و امکان گرفته رتبه سایر بازیکنان در SDK، به خاطر مسئله امنیت، وجود ندارد. در صورتی که نیازمند به گرفتن رتبه دیگران هستید باید از سرویس رایانش استفاده کنید.

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

// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();

// Get your loggedIn user's rank in topPlayers
topPlayers.GetPlayerRankInBackground(rankResponse => {

    // Check if backtory returned result successfully
    if (rankResponse.Successful) {
        // Extract response info
        string leaderboardPosition = "my rank: " + rankResponse.Body.Rank
                + "\n my scores: " + rankResponse.Body.Scores[0];
        // Log it
        Debug.Log(leaderboardPosition);
    }
    else
    {
        // do something based on error code
    }
});

در صورتی که عبارت rankResponse.Successful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت rankResponse.Code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:

Tables Description
200-OK Successful
417-Incorrect data Something is incorrect in leaderboard
400-Bad Request LeaderboardId is null or invalid
500-Internal Server Error Data access was unsuccessful
503-Service Unavailable Backtory is unavailable right now

نفرات برتر در لیدربورد

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

// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();

// Request for top 100 to backtory
topPlayers.GetTopPlayersInBackground(100, leaderboardResponse => {

    // Checking if response was fetched successfully
    if (leaderboardResponse.Successful)
    {
        // Getting first person (Number 1) in leaderboard
        BacktoryLeaderBoard.UserProfile topPlayer =
                leaderboardResponse.Body.UsersProfile[0];
        string username = topPlayer.UserBriefProfile.UserName;
        IList<int> scores = topPlayer.Scores;

        // Logging best player
        Debug.Log("best player is: " + username
                + "\n scoring: " + scores);
    }
    else
    {
        // do something based on error code
    }
});

توجه: محدودیت تعداد نفرات بالای لیدربورد ۱۰۰ است و اگر شما برای بیش از این تعداد درخواست دهید، با خطا مواجه خواهید شد.

در صورتی که عبارت leaderboardResponse.Successful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت leaderboardResponse.Code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:

Tables Description
200-OK Successful
417-Incorrect data Something is incorrect in leaderboard
400-Bad Request LeaderboardId is null or invalid
500-Internal Server Error Data access was unsuccessful
503-Service Unavailable Backtory is unavailable right now

اطرافیان من در لیدربورد

یکی از المان‌های اپلیکیشن که برای کاربران جذاب است، این است که بدانند در لیدربورد بازی رتبه چندم را دارا هستند و اختلاف‌شان با اطرافیان چقدر است. به این ترتیب می‌توانند میزان زمانی که باید صرف بازی کنند و نتیجه‌ای که در لیدربورد آنها خواهد داشت را تخمین زده و به بازی بپردازند. به این عمل Around-me گفته می‌شود.

در صورتی که می‌خواهید ۵ نفر بالا و ۵ نفر پایین خود را دریافت کنید باید به تابع Around-me عدد ۱۰ را پاس بدهید. بکتوری در جواب یک آرایه حداکثر به طول ۱۱ برمی‌گرداند که شامل ۵ نفر بالا، کاربر شما و ۵ نفر پایین خواهد بود. دقت کنید که در صورتی که کاربر شما در شرایط مرزی باشد، برای مثال نفر اول لیدربورد باشد، ۵ نفر بالا برایش معنی ندارد و جواب یک آرایه به طول ۶ خواهد بود که شامل کاربر فعلی در صدر و ۵ کاربر پایین او خواهد شد.

کد زیر یک درخواست ساده برای دریافت اطلاعات ۱ نفر بالا و ۱ نفر پایین را به سرور بکتوری می‌دهد:

// Create a leaderboard object
TopPlayersLeaderBoard topPlayers = new TopPlayersLeaderBoard();

// Request for 2 players which are around me is TopPlayers leaderboard,
// Normally, index 0 is above me, index 1 is ME, and index 2 is below me
topPlayers.GetPlayersAroundMeInBackground(2, leaderboardResponse => {

    // Checking server response
    if (leaderboardResponse.Successful)
    {   // = result is valid
        // Get above and below players
        BacktoryLeaderBoard.UserProfile aboveMePlayer =
                leaderboardResponse.Body.UsersProfile[0];
        BacktoryLeaderBoard.UserProfile belowMePlayer =
                leaderboardResponse.Body.UsersProfile[2];

        // Logging result
        Debug.Log("you are behind "
            + aboveMePlayer.UserBriefProfile.UserName
            + "\n but better than "
            + belowMePlayer.UserBriefProfile.UserName);
    }
    else
    {
        // do something based on error code
    }
});

در مثال بالا عدد ۲ بدین معنی است که می‌خواهید ۱ نفر بالا و ۱ نفر پایین کاربر فعلی را دریافت کنید. محدودیت تعداد اطرافیانی که بکتوری در اختیار شما می‌گذارید عدد ۲۰ است (یعنی ۱۰ نفر بالا و ۱۰ نفر پایین) و اگر عدد بالاتری را درخواست کنید با خطا مواجه خواهید شد.

در صورتی که عبارت leaderboardResponse.Successful برابر true باشد اطلاعات با موفقیت دریافت شده است و در غیر این صورت، عبارت leaderboardResponse.Code نوع خطا را به شما نشان خواهد داد که یکی از مقادیر زیر است:

Tables Description
200-OK Successful
417-Incorrect data Something is incorrect in leaderboard
400-Bad Request LeaderboardId is null or invalid
500-Internal Server Error Data access was unsuccessful
503-Service Unavailable Backtory is unavailable right now